atlas

package
v0.0.0-...-0a40532 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2017 License: MIT Imports: 5 Imported by: 0

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

type ErrStructureMismatch struct {
	TypeName string
	Reason   string
}

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

type MarshalTransformFunc func(liveForm reflect.Value) (serialForm reflect.Value, err error)

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 (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

type UnmarshalTransformFunc func(serialForm reflect.Value) (liveForm reflect.Value, err error)

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.

Directories

Path Synopsis
commonatlases is a package full of `atlas.Entry` definions for common types in the standard library.
commonatlases is a package full of `atlas.Entry` definions for common types in the standard library.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL