Documentation
¶
Overview ¶
Atlas types are used to define how to map Go values into refmt token streams.
Atlas information may be autogenerated based on struct tags automatically, but you can also specify custom AtlasEntry info to use advanced features and define custom transformations.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Atlas ¶
type Atlas struct {
// contains filtered or unexported fields
}
func Build ¶
func Build(entries ...*AtlasEntry) (Atlas, error)
func MustBuild ¶
func MustBuild(entries ...*AtlasEntry) Atlas
func (Atlas) Get ¶
func (atl Atlas) Get(rtid uintptr) (*AtlasEntry, bool)
Gets the AtlasEntry for a typeID. Used by obj package, not meant for user facing.
func (Atlas) GetEntryByTag ¶
func (atl Atlas) GetEntryByTag(tag int) (*AtlasEntry, bool)
Gets the AtlasEntry for a tag int. Used by obj package, not meant for user facing.
type AtlasEntry ¶
type AtlasEntry struct { // The reflect info of the type this morphism is regarding. Type reflect.Type // Transforms the value we reached by walking (the 'live' value -- which // must be of `this.Type`) into another value (the 'serialable' value -- // which will be of `this.MarshalTransformTargetType`). // // The target type may be anything, even of a completely different Kind! // // This transform func runs first, then the resulting value is // serialized (by running through the path through Atlas again, so // chaining of transform funcs is supported, though not recommended). MarshalTransformFunc MarshalTransformFunc // The type of value we expect after using the MarshalTransformFunc. // // The match between transform func and target type should be checked // during construction of this AtlasEntry. MarshalTransformTargetType reflect.Type // Expects a different type (the 'serialable' value -- which will be of // 'this.UnmarshalTransformTargetType') than the value we reached by // walking (the 'live' value -- which must be of `this.Type`). // // The target type may be anything, even of a completely different Kind! // // The unmarshal of that target type will be run first, then the // resulting value is fed through this function to produce the real value, // which is then placed correctly into bigger mid-unmarshal object tree. // // For non-primitives, unmarshal of the target type will always target // an empty pointer or empty slice, roughly as per if it was // operating on a value produced by `TargetType.New()`. UnmarshalTransformFunc UnmarshalTransformFunc // The type of value we will manufacture an instance of and unmarshal // into, then when done provide to the UnmarshalTransformFunc. // // The match between transform func and target type should be checked // during construction of this AtlasEntry. UnmarshalTransformTargetType reflect.Type // A "tag" to emit when marshalling this type of value; // and when unmarshalling, this tag will cause unmarshal to pick // this atlas (and if there's conflicting type info, error). Tag int // Flag for whether the Tag feature should be used (zero is a valid tag). Tagged bool // A mapping of fields in a struct to serial keys. // Only valid if `this.Type.Kind() == Struct`. StructMap *StructMap // A validation function which will be called for the whole value // after unmarshalling reached the end of the object. // If it returns an error, the entire unmarshal will error. // // Not used in marshalling. // Not reachable if an UnmarshalTransform is set. ValidateFn func(v interface{}) error }
The AtlasEntry is a declarative roadmap of what we should do for marshal and unmarshal of a single object, keyed by type.
There are a lot of paths your mappings might want to take:
- For a struct type, you may simply want to specify some alternate keys, or some to leave out, etc.
- For an interface type, you probably want to specify one of our interface muxing strategies with a mapping between enumstr:typeinfo (and, what to do if we get a struct we don't recognize).
- For a string, int, or other primitive, you don't need to say anything: defaults will DTRT.
- For a typedef'd string, int, or other primitive, you *still* don't need to say anything: but, if you want custom behavior (say, transform the string to an int at the last second, and back again), you can specify transformer functions for that.
- For a struct type that you want to turn into a whole different kind (like a string): use those same transform functions. (You'll no longer need a FieldMap.)
- For the most esoteric needs, you can fall all the way back to providing a custom MarshalMachine (but avoid that; it's a lot of work, and one of these other transform methods should suffice).
func AutogenerateStructMapEntry ¶
func AutogenerateStructMapEntry(rt reflect.Type) *AtlasEntry
func AutogenerateStructMapEntryUsingTags ¶
func AutogenerateStructMapEntryUsingTags(rt reflect.Type, tagName string) *AtlasEntry
type BuilderCore ¶
type BuilderCore struct {
// contains filtered or unexported fields
}
Intermediate step in building an AtlasEntry: use `BuildEntry` to get one of these to start with, then call one of the methods on this type to get a specialized builder which has the methods relevant for setting up that specific kind of mapping.
One full example of using this builder may look like the following:
atlas.BuildEntry(Formula{}).StructMap().Autogenerate().Complete()
Some intermediate manipulations may be performed on this object, for example setting the "tag" (if you want to use cbor tagging), before calling the specializer method. In this case, just keep chaining the configuration calls like so:
atlas.BuildEntry(Formula{}).UseTag(4000) .StructMap().Autogenerate().Complete()
func BuildEntry ¶
func BuildEntry(typeHintObj interface{}) *BuilderCore
func (*BuilderCore) StructMap ¶
func (x *BuilderCore) StructMap() *BuilderStructMap
func (*BuilderCore) Transform ¶
func (x *BuilderCore) Transform() *BuilderTransform
func (*BuilderCore) UseTag ¶
func (x *BuilderCore) UseTag(tag int) *BuilderCore
type BuilderStructMap ¶
type BuilderStructMap struct {
// contains filtered or unexported fields
}
func (*BuilderStructMap) AddField ¶
func (x *BuilderStructMap) AddField(fieldName string, mapping StructMapEntry) *BuilderStructMap
Add a field to the mapping based on its name.
Given a struct:
struct{ X int Y struct{ Z int } }
`AddField("X", {"x", ...}) will cause that field to be serialized as key "x"; `AddField("Y.Z", {"z", ...})` will cause that *nested* field to be serialized as key "z" in the same object (e.g. "x" and "z" will be siblings).
Returns the mutated builder for convenient call chaining.
If the fieldName string doesn't map onto the structure type info, a panic will be raised.
func (*BuilderStructMap) Autogenerate ¶
func (x *BuilderStructMap) Autogenerate() *BuilderStructMap
Automatically generate mappings by looking at the struct type info, taking any hints from tags, and appending that to the builder.
You may use autogeneration in concert with manually adding field mappings, though if doing so be mindful not to map the same fields twice.
func (*BuilderStructMap) Complete ¶
func (x *BuilderStructMap) Complete() *AtlasEntry
type BuilderTransform ¶
type BuilderTransform struct {
// contains filtered or unexported fields
}
func (*BuilderTransform) Complete ¶
func (x *BuilderTransform) Complete() *AtlasEntry
func (*BuilderTransform) TransformMarshal ¶
func (x *BuilderTransform) TransformMarshal(trFunc MarshalTransformFunc, toType reflect.Type) *BuilderTransform
func (*BuilderTransform) TransformUnmarshal ¶
func (x *BuilderTransform) TransformUnmarshal(trFunc UnmarshalTransformFunc, toType reflect.Type) *BuilderTransform
type ErrStructureMismatch ¶
Error type raised when initializing an Atlas, and field entries do not resolve against the type. (If you recently refactored names of fields in your types, check to make sure you updated any references to those fields by name to match!)
func (ErrStructureMismatch) Error ¶
func (e ErrStructureMismatch) Error() string
type MarshalTransformFunc ¶
func MakeMarshalTransformFunc ¶
func MakeMarshalTransformFunc(fn interface{}) (MarshalTransformFunc, reflect.Type)
Takes a wildcard object which must be `func (live T1) (serialable T2, error)` and returns a MarshalTransformFunc and the typeinfo of T2.
type ReflectRoute ¶
type ReflectRoute []int
func (ReflectRoute) TraverseToValue ¶
func (rr ReflectRoute) TraverseToValue(v reflect.Value) reflect.Value
type StructMap ¶
type StructMap struct { // A slice of descriptions of each field in the type. // Each entry specifies the name by which each field should be referenced // when serialized, and defines a way to get an address to the field. Fields []StructMapEntry }
type StructMapEntry ¶
type StructMapEntry struct { // The field name; will be emitted as token during marshal, and used for // lookup during unmarshal. Required. SerialName string ReflectRoute ReflectRoute // reflection generates these. Type reflect.Type // type to expect on the far side of the ReflectRoute. // If true, marshalling will skip this field if its the zero value. OmitEmpty bool // contains filtered or unexported fields }
type StructMapEntry_byFieldRoute ¶
type StructMapEntry_byFieldRoute []StructMapEntry
StructMapEntry_byFieldRoute sorts field by FieldRoute sequence (e.g., roughly source declaration order within each type).
func (StructMapEntry_byFieldRoute) Len ¶
func (x StructMapEntry_byFieldRoute) Len() int
func (StructMapEntry_byFieldRoute) Less ¶
func (x StructMapEntry_byFieldRoute) Less(i, j int) bool
func (StructMapEntry_byFieldRoute) Swap ¶
func (x StructMapEntry_byFieldRoute) Swap(i, j int)
type StructMapEntry_byName ¶
type StructMapEntry_byName []StructMapEntry
StructMapEntry_byName sorts field by name, breaking ties with depth, then breaking ties with "name came from tag", then breaking ties with FieldRoute sequence.
func (StructMapEntry_byName) Len ¶
func (x StructMapEntry_byName) Len() int
func (StructMapEntry_byName) Less ¶
func (x StructMapEntry_byName) Less(i, j int) bool
func (StructMapEntry_byName) Swap ¶
func (x StructMapEntry_byName) Swap(i, j int)
type UnmarshalTransformFunc ¶
func MakeUnmarshalTransformFunc ¶
func MakeUnmarshalTransformFunc(fn interface{}) (UnmarshalTransformFunc, reflect.Type)
Takes a wildcard object which must be `func (serialable T1) (live T2, error)` and returns a UnmarshalTransformFunc and the typeinfo of T1.