Documentation ¶
Overview ¶
Package rs provides rendering suffix support for yaml
Index ¶
- Constants
- Variables
- func InitRecursively(fv reflect.Value, opts *Options)
- func MergeMap(original, additional map[string]interface{}, appendList bool, ...) (map[string]interface{}, error)
- func NormalizeRawData(rawData interface{}) (interface{}, error)
- func UniqueList(dt []interface{}) []interface{}
- type AnyObject
- type AnyObjectMap
- type BaseField
- type Field
- type InterfaceTypeHandleFunc
- type InterfaceTypeHandler
- type JSONPatchSpec
- type MergeSource
- type Options
- type PatchSpec
- type RenderingHandleFunc
- type RenderingHandler
- type TypeHint
- type TypeHintBool
- type TypeHintFloat
- type TypeHintInt
- type TypeHintNone
- type TypeHintObject
- type TypeHintObjects
- type TypeHintStr
Examples ¶
Constants ¶
const ( TagNameRS = "rs" TagName = TagNameRS )
Struct field tag names used by this package
Variables ¶
var (
ErrInterfaceTypeNotHandled = errors.New("interface type not handled")
)
Functions ¶
func InitRecursively ¶
InitRecursively trys to call Init on all fields implementing Field interface
func NormalizeRawData ¶ added in v0.5.1
func NormalizeRawData(rawData interface{}) (interface{}, error)
func UniqueList ¶ added in v0.1.1
func UniqueList(dt []interface{}) []interface{}
Types ¶
type AnyObject ¶
type AnyObject struct {
// contains filtered or unexported fields
}
AnyObject is a `interface{}` equivalent with rendering suffix support
func (*AnyObject) MarshalJSON ¶
func (*AnyObject) MarshalYAML ¶
func (*AnyObject) NormalizedValue ¶ added in v0.3.0
func (o *AnyObject) NormalizedValue() interface{}
NormalizedValue returns underlying value of the AnyObject with primitive types that is:
for maps: map[string]interface{} for slices: []interface{} and primitive types for scalar types
should be called after fields being resolved
func (*AnyObject) ResolveFields ¶
func (o *AnyObject) ResolveFields(rc RenderingHandler, depth int, names ...string) error
func (*AnyObject) UnmarshalYAML ¶
type AnyObjectMap ¶ added in v0.3.0
AnyObjectMap is a `map[string]interface{}` equivalent with rendering suffix support
func (*AnyObjectMap) MarshalJSON ¶ added in v0.3.0
func (aom *AnyObjectMap) MarshalJSON() ([]byte, error)
func (*AnyObjectMap) MarshalYAML ¶ added in v0.3.0
func (aom *AnyObjectMap) MarshalYAML() (interface{}, error)
func (*AnyObjectMap) NormalizedValue ¶ added in v0.3.0
func (aom *AnyObjectMap) NormalizedValue() map[string]interface{}
NormalizedValue returns value of the AnyObjectMap with type map[string]interface{}
type BaseField ¶
type BaseField struct {
// contains filtered or unexported fields
}
func (*BaseField) HasUnresolvedField ¶
func (*BaseField) Inherit ¶
Inherit unresolved fields from another BaseField useful when you are merging two structs and want to resolve only once to get all unresolved fields set
after a successful function call, f wiil be able to resolve its struct fields with unresolved values from b and its own
func (*BaseField) MarshalYAML ¶ added in v0.4.0
MarshalYAML implements yaml.Marshaler by making a map of all fields known to BaseField
You can opt-out with build tag `rs_noyamlmarshaler`
func (*BaseField) ResolveFields ¶
func (f *BaseField) ResolveFields(rc RenderingHandler, depth int, names ...string) error
Example ¶
type MyStruct struct { rs.BaseField `yaml:"-"` MyValue string `yaml:"my_value"` } // required: // initialize you data object // before marshaling/unmarshaling/resolving s := rs.Init(&MyStruct{}, nil).(*MyStruct) // unmarshal yaml data using rendering suffix err := yaml.Unmarshal([]byte(`{ my_value@my-renderer: 123 }`), s) if err != nil { panic(err) } err = s.ResolveFields( // implement your own renderer rs.RenderingHandleFunc( func(renderer string, rawData interface{}) (result []byte, err error) { // usually you should have rawData normalized as golang types // so you don't have to tend to low level *yaml.Node objects rawData, err = rs.NormalizeRawData(rawData) if err != nil { return nil, err } switch vt := rawData.(type) { case string: return []byte(vt), nil case []byte: return vt, nil default: return []byte("hello"), nil } }, ), -1, ) if err != nil { panic(err) } fmt.Println(s.MyValue)
Output: hello
func (*BaseField) UnmarshalYAML ¶
UnmarshalYAML handles parsing of rendering suffix and normal yaml unmarshaling
type Field ¶
type Field interface { // A Field must implement yaml.Unmarshaler interface to process rendering suffix // in yaml key yaml.Unmarshaler // ResolveFields sets struct field values with data from unmarshaled yaml // // depth controls to what level this function call goes // when depth >= 1, resolve inner fields until reaching depth limit (depth == 0) // when depth == 0, do nothing // when depth < 0, resolve recursively // // names limits which fields to be resolved, their values are derived from // your field tags // When it's not empty, resolve specified fields only, otherwise, resolve all exported fields // in the struct. ResolveFields(rc RenderingHandler, depth int, names ...string) error }
Field defines methods required for rendering suffix support
these methods are implemented by BaseField, so usually you should just embed BaseField in your struct as the very first field
type InterfaceTypeHandleFunc ¶
InterfaceTypeHandleFunc is a helper type to wrap your function as InterfaceTypeHandler
type InterfaceTypeHandler ¶
type InterfaceTypeHandler interface { // Create request interface type using yaml information Create(typ reflect.Type, yamlKey string) (interface{}, error) }
InterfaceTypeHandler is used when setting values for interface{} typed field
type JSONPatchSpec ¶
type JSONPatchSpec struct { BaseField `yaml:"-" json:"-"` Operation string `yaml:"op"` Path string `yaml:"path"` Value *yaml.Node `yaml:"value,omitempty"` // Resolve rendering suffix in value before being applied // // Defaults to `true` Resolve *bool `yaml:"resolve"` // Select part of the value for patching // // this action happens before patching Select string `yaml:"select"` }
JSONPatchSpec per rfc6902
type MergeSource ¶
type MergeSource struct { BaseField `yaml:"-" json:"-"` // Value for the source Value *yaml.Node `yaml:"value,omitempty"` // Resolve rendering suffix in value if any before being merged // // Defaults to `true` Resolve *bool `yaml:"resolve"` // Select some data from the source Select string `yaml:"select,omitempty"` }
type Options ¶ added in v0.4.0
type Options struct { // InterfaceTypeHandler handles interface value creation for any inner field // with a interface{...} type (including []interface{...} and map[string]interface{...}) // // defaults to `nil` InterfaceTypeHandler InterfaceTypeHandler // DataTagNamespace used for struct field tag parsing // you can set it to json to use json tag // // supported tag values are: // - <first tag value as data field name> // - inline // - omitempty // // unsupported tag values are ignored // // defaults to `yaml` DataTagNamespace string // AllowUnknownFields whether restrict unmarshaling to known fields // // NOTE: if there is a map field in struct with field type `rs:"other"` // even when AllowUnknownFields is set to false, it still gets these unknown // fields marshaled to that map field // // defaults to `false` AllowUnknownFields bool }
type PatchSpec ¶
type PatchSpec struct { BaseField `yaml:"-" json:"-"` // Value for the renderer // // say we have a yaml list (`[bar]`) stored at https://example.com/bar.yaml // // foo@http!: // value: https://example.com/bar.yaml // merge: { value: [foo] } // // then the resolved value of foo will be `[bar, foo]` Value *yaml.Node `yaml:"value"` // Resolve rendering suffix in value if any before being patched // // Defaults to `true` Resolve *bool `yaml:"resolve"` // Merge additional data into Value // // this action happens first Merge []MergeSource `yaml:"merge,omitempty"` // Patch Value using standard rfc6902 json-patch // // this action happens after merge Patch []JSONPatchSpec `yaml:"patch"` // Select part of the data as final result // // this action happens after merge and patch Select string `yaml:"select"` // Unique to make sure elements in the sequence is unique // // only effective when Value is yaml sequence Unique bool `yaml:"unique"` // MapListItemUnique to ensure items are unique in all merged lists respectively // lists with no merge data input are untouched MapListItemUnique bool `yaml:"map_list_item_unique"` // MapListAppend to append lists instead of replacing existing list MapListAppend bool `yaml:"map_list_append"` }
PatchSpec is the input definition for renderers with a patching suffix
func (*PatchSpec) ApplyTo ¶
func (s *PatchSpec) ApplyTo(rc RenderingHandler, valueData interface{}) (interface{}, error)
Apply Merge and Patch to Value, Unique is ensured if set to true
type RenderingHandleFunc ¶ added in v0.4.0
RenderingHandleFunc is a helper type to wrap your function as RenderingHandler
func (RenderingHandleFunc) RenderYaml ¶ added in v0.4.0
func (f RenderingHandleFunc) RenderYaml(renderer string, rawData interface{}) (result []byte, err error)
type RenderingHandler ¶
type RenderingHandler interface { // RenderYaml transforms rawData to result through the renderer // // renderer is the name of your renderer without type hint (`?<hint>`) and patch suffix (`!`) // // rawData is the input to your renderer, which can have one of following types // - golang primitive types (e.g. int, float32) // - map[string]interface{} // - []interface{} // - *yaml.Node // when it's not *yaml.Node type, it was patched by built-in data patching support // (as indicated by the `!` suffix to your renderer) // // Your renderer is responsible for casting it to its desired data type RenderYaml(renderer string, rawData interface{}) (result []byte, err error) }
RenderingHandler is used when resolving yaml fields
type TypeHint ¶ added in v0.3.0
type TypeHint interface { String() string // contains filtered or unexported methods }
func ParseTypeHint ¶ added in v0.3.0
type TypeHintBool ¶ added in v0.7.0
type TypeHintBool struct{}
func (TypeHintBool) String ¶ added in v0.7.0
func (TypeHintBool) String() string
type TypeHintFloat ¶ added in v0.3.0
type TypeHintFloat struct{}
func (TypeHintFloat) String ¶ added in v0.5.1
func (TypeHintFloat) String() string
type TypeHintInt ¶ added in v0.3.0
type TypeHintInt struct{}
func (TypeHintInt) String ¶ added in v0.5.1
func (TypeHintInt) String() string
type TypeHintNone ¶ added in v0.3.0
type TypeHintNone struct{}
func (TypeHintNone) String ¶ added in v0.5.1
func (TypeHintNone) String() string
type TypeHintObject ¶ added in v0.3.0
type TypeHintObject struct{}
func (TypeHintObject) String ¶ added in v0.5.1
func (TypeHintObject) String() string
type TypeHintObjects ¶ added in v0.3.0
type TypeHintObjects struct{}
func (TypeHintObjects) String ¶ added in v0.5.1
func (TypeHintObjects) String() string
type TypeHintStr ¶ added in v0.3.0
type TypeHintStr struct{}
func (TypeHintStr) String ¶ added in v0.5.1
func (TypeHintStr) String() string