conversion

package
v0.0.0-...-e20f597 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2014 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package conversion provides go object versioning and encoding/decoding mechanisms.

Specifically, conversion provides a way for you to define multiple versions of the same object. You may write functions which implement conversion logic, but for the fields which did not change, copying is automated. This makes it easy to modify the structures you use in memory without affecting the format you store on disk or respond to in your external API calls.

The second offering of this package is automated encoding/decoding. The version and type of the object is recorded in the output, so it can be recreated upon reading. Currently, conversion writes JSON output, and interprets both JSON and YAML input.

In the future, we plan to more explicitly separate the above two mechanisms, and add more serialization options, such as gob.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Converter

type Converter struct {

	// If true, print helpful debugging info. Quite verbose.
	Debug DebugLogger
	// contains filtered or unexported fields
}

Converter knows how to convert one type to another.

func NewConverter

func NewConverter() *Converter

NewConverter makes a new Converter object.

func (*Converter) Convert

func (c *Converter) Convert(src, dest interface{}, flags FieldMatchingFlags) error

Convert will translate src to dest if it knows how. Both must be pointers. If no conversion func is registered and the default copying mechanism doesn't work on this type pair, an error will be returned. Not safe for objects with cyclic references!

func (*Converter) Register

func (c *Converter) Register(conversionFunc interface{}) error

Register registers a conversion func with the Converter. conversionFunc must take two parameters, the input and output type. It must take a pointer to each. It must return an error.

Example: c.Register(func(in *Pod, out *v1beta1.Pod) error { ... return nil })

type DebugLogger

type DebugLogger interface {
	Logf(format string, args ...interface{})
}

DebugLogger allows you to get debugging messages if necessary.

type FieldMatchingFlags

type FieldMatchingFlags int

FieldMatchingType contains a list of ways in which struct fields could be copied. These constants may be | combined.

const (
	// Loop through destination fields, search for matching source
	// field to copy it from. Source fields with no corresponding
	// destination field will be ignored. If SourceToDest is
	// specified, this flag is ignored. If niether is specified,
	// or no flags are passed, this flag is the default.
	DestFromSource FieldMatchingFlags = 0
	// Loop through source fields, search for matching dest field
	// to copy it into. Destination fields with no corresponding
	// source field will be ignored.
	SourceToDest FieldMatchingFlags = 1 << iota
	// Don't treat it as an error if the corresponding source or
	// dest field can't be found.
	IgnoreMissingFields
	// Don't require type names to match.
	AllowDifferentFieldTypeNames
)

func (FieldMatchingFlags) IsSet

Returns true if the given flag or combination of flags is set.

type MetaInsertionFactory

type MetaInsertionFactory interface {
	// Create should make a new object with two fields.
	// This object will be used to encode this metadata along with your
	// API objects, so the tags on the fields you use shouldn't conflict.
	Create(version, kind string) interface{}
	// Interpret should take the same type of object that Create creates.
	// It should return the version and kind information from this object.
	Interpret(interface{}) (version, kind string)
}

MetaInsertionFactory is used to create an object to store and retrieve the version and kind information for all objects. The default uses the keys "version" and "kind" respectively. The object produced by this factory is used to clear the version and kind fields in memory, so it must match the layout of your actual api structs. (E.g., if you have your version and kind field inside an inlined struct, this must produce an inlined struct with the same field name.)

type Scheme

type Scheme struct {

	// Indent will cause the JSON output from Encode to be indented, iff it is true.
	Indent bool

	// InternalVersion is the default internal version. It is recommended that
	// you use "" for the internal version.
	InternalVersion string

	// ExternalVersion is the default external version.
	ExternalVersion string

	// MetaInsertionFactory is used to create an object to store and retrieve
	// the version and kind information for all objects. The default uses the
	// keys "version" and "kind" respectively.
	MetaInsertionFactory MetaInsertionFactory
	// contains filtered or unexported fields
}

Scheme defines an entire encoding and decoding scheme.

func NewScheme

func NewScheme() *Scheme

NewScheme manufactures a new scheme.

func (*Scheme) AddConversionFuncs

func (s *Scheme) AddConversionFuncs(conversionFuncs ...interface{}) error

AddConversionFuncs adds functions to the list of conversion functions. The given functions should know how to convert between two of your API objects, or their sub-objects. We deduce how to call these functions from the types of their two parameters; see the comment for Converter.Register.

Note that, if you need to copy sub-objects that didn't change, it's safe to call s.Convert() inside your conversionFuncs, as long as you don't start a conversion chain that's infinitely recursive.

Also note that the default behavior, if you don't add a conversion function, is to sanely copy fields that have the same names and same type names. It's OK if the destination type has extra fields, but it must not remove any. So you only need to add conversion functions for things with changed/removed fields.

func (*Scheme) AddKnownTypes

func (s *Scheme) AddKnownTypes(version string, types ...interface{})

AddKnownTypes registers all types passed in 'types' as being members of version 'version. Encode() will refuse objects unless their type has been registered with AddKnownTypes. All objects passed to types should be structs, not pointers to structs. The name that go reports for the struct becomes the "kind" field when encoding.

func (*Scheme) Convert

func (s *Scheme) Convert(in, out interface{}) error

Convert will attempt to convert in into out. Both must be pointers. For easy testing of conversion functions. Returns an error if the conversion isn't possible.

func (*Scheme) DataVersionAndKind

func (s *Scheme) DataVersionAndKind(data []byte) (version, kind string, err error)

DataAPIVersionAndKind will return the APIVersion and Kind of the given wire-format enconding of an API Object, or an error.

func (*Scheme) Decode

func (s *Scheme) Decode(data []byte) (interface{}, error)

Decode converts a YAML or JSON string back into a pointer to an api object. Deduces the type based upon the fields added by the MetaInsertionFactory technique. The object will be converted, if necessary, into the s.InternalVersion type before being returned. Decode will refuse to decode objects without a version, because that's probably an error.

func (*Scheme) DecodeInto

func (s *Scheme) DecodeInto(data []byte, obj interface{}) error

DecodeInto parses a YAML or JSON string and stores it in obj. Returns an error if data.Kind is set and doesn't match the type of obj. Obj should be a pointer to an api type. If obj's version doesn't match that in data, an attempt will be made to convert data into obj's version.

func (*Scheme) Encode

func (s *Scheme) Encode(obj interface{}) (data []byte, err error)

Encode turns the given api object into an appropriate JSON string. Obj may be a pointer to a struct, or a struct. If a struct, a copy will be made, therefore it's recommended to pass a pointer to a struct. The type must have been registered.

Memory/wire format differences:

  • Having to keep track of the Kind and Version fields makes tests very annoying, so the rule is that they are set only in wire format (json), not when in native (memory) format. This is possible because both pieces of information are implicit in the go typed object.
  • An exception: note that, if there are embedded API objects of known type, for example, PodList{... Items []Pod ...}, these embedded objects must be of the same version of the object they are embedded within, and their Version and Kind must both be empty.
  • Note that the exception does not apply to a generic APIObject type which recursively does Encode()/Decode(), and is capable of expressing any API object.
  • Only versioned objects should be encoded. This means that, if you pass a native object, Encode will convert it to a versioned object. For example, an api.Pod will get converted to a v1beta1.Pod. However, if you pass in an object that's already versioned (v1beta1.Pod), Encode will not modify it.

The purpose of the above complex conversion behavior is to allow us to change the memory format yet not break compatibility with any stored objects, whether they be in our storage layer (e.g., etcd), or in user's config files.

func (*Scheme) EncodeOrDie

func (s *Scheme) EncodeOrDie(obj interface{}) string

EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.

func (*Scheme) EncodeToVersion

func (s *Scheme) EncodeToVersion(obj interface{}, destVersion string) (data []byte, err error)

EncodeToVersion is like Encode, but you may choose the version.

func (*Scheme) NewObject

func (s *Scheme) NewObject(versionName, typeName string) (interface{}, error)

NewObject returns a new object of the given version and name, or an error if it hasn't been registered.

func (*Scheme) ObjectVersionAndKind

func (s *Scheme) ObjectVersionAndKind(obj interface{}) (apiVersion, kind string, err error)

ObjectVersionAndKind returns the API version and kind of the go object, or an error if it's not a pointer or is unregistered.

func (*Scheme) SetVersionAndKind

func (s *Scheme) SetVersionAndKind(version, kind string, obj interface{}) error

SetVersionAndKind sets the version and kind fields (with help from MetaInsertionFactory). Returns an error if this isn't possible. obj must be a pointer.

Jump to

Keyboard shortcuts

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