marshal

package
v0.0.0-...-e5fa29d Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2021 License: Apache-2.0 Imports: 6 Imported by: 20

Documentation

Overview

Package marshal implements encoding and decoding of Noms values. The mapping between Noms objects and Go values is described in the documentation for the Marshal and Unmarshal functions.

Package marshal implements encoding and decoding of Noms values. The mapping between Noms objects and Go values is described in the documentation for the Marshal and Unmarshal functions.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(vrw types.ValueReadWriter, v interface{}) (types.Value, error)

Marshal converts a Go value to a Noms value.

Marshal traverses the value v recursively. Marshal uses the following type-dependent encodings:

Boolean values are encoded as Noms types.Bool.

Floating point and integer values are encoded as Noms types.Number. At the moment this might lead to some loss in precision because types.Number currently takes a float64.

String values are encoded as Noms types.String.

Slices and arrays are encoded as Noms types.List by default. If a field is tagged with `noms:"set", it will be encoded as Noms types.Set instead.

Maps are encoded as Noms types.Map, or a types.Set if the value type is struct{} and the field is tagged with `noms:"set"`.

Struct values are encoded as Noms structs (types.Struct). Each exported Go struct field becomes a member of the Noms struct unless

  • The field's tag is "-"
  • The field is empty and its tag specifies the "omitempty" option.
  • The field has the "original" tag, in which case the field is used as an initial value onto which the fields of the Go type are added. When combined with the corresponding support for "original" in Unmarshal(), this allows one to find and modify any values of a known subtype.

Additionally, user-defined types can implement the Marshaler interface to provide a custom encoding.

The empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero.

The Noms struct default field name is the Go struct field name where the first character is lower cased, but can be specified in the Go struct field's tag value. The "noms" key in the Go struct field's tag value is the field name. Examples:

// Field is ignored.
Field int `noms:"-"`

// Field appears in a Noms struct as field "myName".
MyName int

// Field appears in a Noms struct as key "myName".
Field int `noms:"myName"`

// Field appears in a Noms struct as key "myName" and the field is
//  omitted from the object if its value is empty, as defined above.
Field int `noms:"myName,omitempty"

// Field appears in a Noms struct as key "field" and the field is
//  omitted from the object if its value is empty, as defined above.
Field int `noms:",omitempty"

The name of the Noms struct is the name of the Go struct where the first character is changed to upper case. You can also implement the StructNameMarshaler interface to get more control over the actual struct name.

Anonymous struct fields are usually marshaled as if their inner exported fields were fields in the outer struct, subject to the usual Go visibility. An anonymous struct field with a name given in its Noms tag is treated as having that name, rather than being anonymous.

Noms values (values implementing types.Value) are copied over without any change.

When marshalling interface{} the dynamic type is used.

Go pointers, complex, function are not supported. Attempting to encode such a value causes Marshal to return an UnsupportedTypeError.

Example
vs := newTestValueStore()
defer vs.Close()

type Person struct {
	Given string
	Male  bool
}
arya, err := Marshal(vs, Person{"Arya", false})
if err != nil {
	fmt.Println(err)
	return
}

fmt.Printf("Given: %s, Male: %t\n", arya.(types.Struct).Get("given").(types.String), arya.(types.Struct).Get("male").(types.Bool))
Output:

Given: Arya, Male: false

func MarshalOpt

func MarshalOpt(vrw types.ValueReadWriter, v interface{}, opt Opt) (nomsValue types.Value, err error)

MarshalOpt is like Marshal but provides additional options.

func MarshalType

func MarshalType(v interface{}) (nt *types.Type, err error)

MarshalType computes a Noms type from a Go type

The rules for MarshalType is the same as for Marshal, except for omitempty which leads to an optional field since it depends on the runtime value and can lead to the property not being present.

If a Go struct contains a noms tag with original the field is skipped since the Noms type depends on the original Noms value which is not available.

Example
type Person struct {
	Given  string
	Female bool
}
var person Person
personNomsType, err := MarshalType(person)
if err != nil {
	fmt.Println(err)
	return
}

fmt.Println(personNomsType.Describe())
Output:

Struct Person {
  female: Bool,
  given: String,
}

func MarshalTypeOpt

func MarshalTypeOpt(v interface{}, opt Opt) (nt *types.Type, err error)

MarshalTypeOpt is like MarshalType but with additional options.

func MustMarshal

func MustMarshal(vrw types.ValueReadWriter, v interface{}) types.Value

MustMarshal marshals a Go value to a Noms value using the same rules as Marshal(). Panics on failure.

func MustMarshalOpt

func MustMarshalOpt(vrw types.ValueReadWriter, v interface{}, opt Opt) types.Value

MustMarshalOpt is like MustMarshal, but with additional options.

func MustMarshalType

func MustMarshalType(v interface{}) (nt *types.Type)

MustMarshalType computes a Noms type from a Go type or panics if there is an error.

func MustMarshalTypeOpt

func MustMarshalTypeOpt(v interface{}, opt Opt) (nt *types.Type)

MustMarshalTypeOpt is like MustMarshalType but provides additional options.

func MustUnmarshal

func MustUnmarshal(v types.Value, out interface{})

Unmarshals a Noms value into a Go value using the same rules as Unmarshal(). Panics on failure.

func MustUnmarshalOpt

func MustUnmarshalOpt(v types.Value, opt Opt, out interface{})

MustUnmarshalOpt is like MustUnmarshal but with additional options.

func Unmarshal

func Unmarshal(v types.Value, out interface{}) (err error)

Unmarshal converts a Noms value into a Go value. It decodes v and stores the result in the value pointed to by out.

Unmarshal uses the inverse of the encodings that Marshal uses with the following additional rules:

To unmarshal a Noms struct into a Go struct, Unmarshal matches incoming object fields to the fields used by Marshal (either the struct field name or its tag). Unmarshal will only set exported fields of the struct. The name of the Go struct must match (ignoring case) the name of the Noms struct. All exported fields on the Go struct must be present in the Noms struct, unless the field on the Go struct is marked with the "omitempty" tag. Go struct fields also support the "original" tag which causes the Go field to receive the entire original unmarshaled Noms struct.

To unmarshal a Noms list or set into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. If the Go slice was nil a new slice is created when an element is added.

To unmarshal a Noms list into a Go array, Unmarshal decodes Noms list elements into corresponding Go array elements.

To unmarshal a Noms map into a Go map, Unmarshal decodes Noms key and values into corresponding Go array elements. If the Go map was nil a new map is created if any value is set.

To unmarshal a Noms set into a Go map, the field must be tagged with `noms:",set"`, and it must have a type of map[<value-type>]struct{}. Unmarshal decodes into Go map keys corresponding to the set values and assigns each key a value of struct{}{}.

When unmarshalling onto interface{} the following rules are used:

  • types.Bool -> bool
  • types.List -> []T, where T is determined recursively using the same rules.
  • types.Set -> depends on `noms:",set"` annotation and field type:
  • without the annotation, same as types.List
  • with the annotation, same as types.Map for map[T]struct{} fields and same as types.List for slice fields
  • types.Map -> map[T]V, where T and V is determined recursively using the same rules.
  • types.Number -> float64
  • types.String -> string
  • *types.Type -> *types.Type
  • types.Union -> interface
  • Everything else an error

Unmarshal returns an UnmarshalTypeMismatchError if:

  • a Noms value is not appropriate for a given target type
  • a Noms number overflows the target type
  • a Noms list is decoded into a Go array of a different length
Example
type Person struct {
	Given string
	Male  bool
}
var rickon Person
err := Unmarshal(types.NewStruct("Person", types.StructData{
	"given": types.String("Rickon"),
	"male":  types.Bool(true),
}), &rickon)
if err != nil {
	fmt.Println(err)
	return
}

fmt.Printf("Given: %s, Male: %t\n", rickon.Given, rickon.Male)
Output:

Given: Rickon, Male: true

func UnmarshalOpt

func UnmarshalOpt(v types.Value, opt Opt, out interface{}) (err error)

UnmarshalOpt is like Unmarshal but provides additional options.

Types

type InvalidTagError

type InvalidTagError struct {
	// contains filtered or unexported fields
}

InvalidTagError is returned by encode and decode when the struct field tag is invalid. For example if the field name is not a valid Noms struct field name.

func (*InvalidTagError) Error

func (e *InvalidTagError) Error() string

type InvalidUnmarshalError

type InvalidUnmarshalError struct {
	Type reflect.Type
}

InvalidUnmarshalError describes an invalid argument passed to Unmarshal. (The argument to Unmarshal must be a non-nil pointer.)

func (*InvalidUnmarshalError) Error

func (e *InvalidUnmarshalError) Error() string

type Marshaler

type Marshaler interface {
	// MarshalNoms returns the Noms Value encoding of a type, or an error.
	// nil is not a valid return val - if both val and err are nil, Marshal will
	// panic.
	MarshalNoms(vrw types.ValueReadWriter) (val types.Value, err error)
}

Marshaler is an interface types can implement to provide their own encoding.

type Opt

type Opt struct {
	// Marshal []T or map[T]struct{} to Set<T>, or Unmarhsal Set<T> to map[T]struct{}.
	Set bool
}

type StructNameMarshaler

type StructNameMarshaler interface {
	MarshalNomsStructName() string
}

StructNameMarshaler is an interface that can be implemented to define the name of a Noms struct.

type TypeMarshaler

type TypeMarshaler interface {
	// MarshalNomsType returns the Noms Type encoding of a type, or an error.
	// nil is not a valid return val - if both val and err are nil, MarshalType
	// will panic.
	MarshalNomsType() (t *types.Type, err error)
}

TypeMarshaler is an interface types can implement to provide their own encoding of type.

type UnmarshalTypeMismatchError

type UnmarshalTypeMismatchError struct {
	Value types.Value
	Type  reflect.Type // type of Go value it could not be assigned to
	// contains filtered or unexported fields
}

UnmarshalTypeMismatchError describes a Noms value that was not appropriate for a value of a specific Go type.

func (*UnmarshalTypeMismatchError) Error

type Unmarshaler

type Unmarshaler interface {
	// UnmarshalNoms decodes v, or returns an error.
	UnmarshalNoms(v types.Value) error
}

Unmarshaler is an interface types can implement to provide their own decoding.

You probably want to implement this on a pointer to a type, otherwise calling UnmarshalNoms will effectively do nothing. For example, to unmarshal a MyType you would define:

func (t *MyType) UnmarshalNoms(v types.Value) error {}

type UnsupportedTypeError

type UnsupportedTypeError struct {
	Type    reflect.Type
	Message string
}

UnsupportedTypeError is returned by encode when attempting to encode a type that isn't supported.

func (*UnsupportedTypeError) Error

func (e *UnsupportedTypeError) Error() string

Jump to

Keyboard shortcuts

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