encoding

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Feb 25, 2020 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Arbitrarily encode and decode of message body content.

Spantool's goal is to make a single interface specification for any given content type, so that content can be determined and decoded dynamically based on message headers or mimetype sniffing, removing the need to explicitly call mimetype-specific methods when decoding content.

Specific objectives

1. Clients can send arbitrary object serializations and request back whichever encoding type they are most comfortable with.

2. Service developers do not have to explicitly add support for encoding types to a given service or handler. Support for a mimetype should be able to be added once to a shared library and gotten for free by an entire ecosystem.

3. Content encoding and decoding support should be independent of service pattern. IE, adding support for understanding yaml should upgrade both REST server and http client libraries on a rebuild.

4. Developers can easily extend all of their services to support a new content type by creating their own encoding.

5. All default encoding shipped with spantools can be easily extendable to handle custom types.

Index

Constants

View Source
const BsonListSepString = "\u241E"

BsonListSepString is a delimiter for top-level bson lists, which bson does not not normally support. When multiple documents are being sent in a single payload, the unicode SYMBOL FOR RECORD SEPARATOR is used. (http://fileformat.info/info/unicode/char/241e/index.htm)

Variables

View Source
var BsonListSepBytes = []byte(BsonListSepString)

BsonListSepBytes is a byte representation of BsonListSepString.

Functions

This section is empty.

Types

type BsonCodecOpts

type BsonCodecOpts struct {
	// Type this codec handles encoding / decoding to.
	ValueType reflect.Type

	// Codec to register for this type.
	Codec bsoncodec.ValueCodec
}

BsonCodecOpts holds options for registering new BSON codecs with SpanEngine.

type ContentEngine

type ContentEngine interface {
	// Registers an encoder for a given mimetype.
	SetEncoder(mimeType mimetype.MimeType, encoder Encoder)

	// Registers a decoder for a given mimetype.
	SetDecoder(mimeType mimetype.MimeType, decoder Decoder)

	// Returns true if the engine has a registered encoder for the mimetype.
	HandlesEncode(mimeType mimetype.MimeType) bool

	// Returns true if the engine has a registered decoder for the mimetype.
	HandlesDecode(mimeType mimetype.MimeType) bool

	// Returns true if the engine has a registered encoder AND decoder for the mimetype.
	Handles(mimeType mimetype.MimeType) bool

	// Whether the engine will attempt to encode / decode unknown mimetypes.
	SniffType() bool

	// Decode mimeType content from reader using the decoder for mimeType. Decoded
	// content is stored in contentReceiver.
	Decode(
		mimeType mimetype.MimeType,
		contentReceiver interface{},
		reader io.Reader,
	) (mimetype.MimeType, error)

	// Encode content as mimetype using registered mimeType to writer.
	Encode(
		mimeType mimetype.MimeType,
		content interface{},
		writer io.Writer,
	) (mimetype.MimeType, error)

	PickContentMimeType(
		mimeType mimetype.MimeType, content interface{}, encoding bool,
	) mimetype.MimeType
}

ContentEngine details the contract for a content encoding engine. The goal of the content engine is to allow a common decoding and encoding methodology for any supported mimetype, allowing easy support for client-requested payload encodings, and a shared interface for different types of services to add support for various encoding types.

type Decoder

type Decoder interface {
	// To be implemented by content decoder. Implementation is expected to read content
	// from reader and unmarshal it into contentReceiver. The content engine which is
	// calling Decode is made available through engine, allowing decoders to access
	// engine-level settings.
	Decode(engine ContentEngine, reader io.Reader, contentReceiver interface{}) error
}

Interface for defining a content decoder.

type Encoder

type Encoder interface {
	// To be implemented by content encoder. Implementation is expected to write content
	// to writer. The content engine which is calling Encode is made available through
	// engine, allowing encoding to access engine-level settings.
	Encode(engine ContentEngine, writer io.Writer, content interface{}) error
}

Interface for defining a content encoder.

type JSONExtensionOpts

type JSONExtensionOpts struct {
	ValueType    reflect.Type
	ExtInterface codec.InterfaceExt
}

JSONExtensionOpts holds options For Json Handle extension to add to the handle on server setup.

type SpanEngine

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

SpanEngine is the default implementation of the ContentEngine interface. Implementation is done through an Interface so that the Engine can be extended through type wrapping.

Instantiation

Use NewContentEngine() to create a new SpanEngine.

Default Mimetypes

• plain/text

• application/json

• application/bson

Object encoding/decoders have been selected to be extensible, and SpanEngine exposes functions to let you add custom type handlers to each.

Default JSON Extensions

SpanEngine uses the codec library to encode/decode json (https://godoc.org/github.com/ugorji/go/codec), which allows the definition of extensions. SpanEngine ships with the following types handled:

• UUIDs from "github.com/satori/go.uuid"

• Binary blob data represented as []byte or *[]bytes are represented as a hex string. To signal that this conversion should take place, you must use the named type BinData in the "spantypes" package of this module.

• BSON primitive.Binary data will be decoded as a string for 0x3 subtype (UUID) and a hex string for 0x0 subtype (arbitrary binary data). Other subtypes are not currently supported and will panic.

• BSON raw is converted to a map and THEN encoded to a json object.

Additional json extensions can be registered through the AddJSONExtensions() by passing a slice of JSONExtensionOpts objects.

Default BSON Codecs

SpanEngine handles the encoding and decoding of Bson data through the official bson driver (https://godoc.org/go.mongodb.org/mongo-driver).

See information on defining a bson codec here: https://godoc.org/go.mongodb.org/mongo-driver/bson/bsoncodec

The following type extensions ship with SpanEngine:

• primitive.Binary of subtype 0x3 can be decoded to / encoded from UUID objects from "github.com/satori/go.uuid".

• primitive.Binary of subtype 0x0 can be decoded to / encoded from the BinData named type of []byte in the "spantypes" module.

Default Text/Plain Returns

When encoding to plaintext, format.Sprint is used on the passed object, so any type can be sent and represented as text.

Type Sniffing

If created with "sniffMimeType" set to true, when decoding SpanEngine will attempt to use each decoder until one does not return an error or panic. Because decoders are internally stored in a map, the order of these attempts is not guaranteed to be consistent.

Panics

If an encoder or decoder panics during execution, that panic is caught and returned as an error.

func NewContentEngine

func NewContentEngine(allowSniff bool) (*SpanEngine, error)

func (*SpanEngine) AddBSONCodecs

func (engine *SpanEngine) AddBSONCodecs(codecs []*BsonCodecOpts) error

Adds BSON codecs to engine for use when encoding/decoding bson data.

func (*SpanEngine) AddJSONExtensions

func (engine *SpanEngine) AddJSONExtensions(extensions []*JSONExtensionOpts) error

Adds JSON extensions to handle.

func (*SpanEngine) BSONRegistry

func (engine *SpanEngine) BSONRegistry() *bsoncodec.Registry

Returns the internal bsoncodec.BSONRegistry used by the bson encoder/decoder.

func (*SpanEngine) Decode

func (engine *SpanEngine) Decode(
	mimeType mimetype.MimeType,
	contentReceiver interface{},
	reader io.Reader,
) (mimetype.MimeType, error)

func (*SpanEngine) Encode

func (engine *SpanEngine) Encode(
	mimeType mimetype.MimeType,
	content interface{},
	writer io.Writer,
) (mimetype.MimeType, error)

func (*SpanEngine) Handles

func (engine *SpanEngine) Handles(mimeType mimetype.MimeType) bool

Whether the SpanEngine has a registered decoder AND encoder for mimeType.

func (*SpanEngine) HandlesDecode

func (engine *SpanEngine) HandlesDecode(mimeType mimetype.MimeType) bool

Whether the SpanEngine has a registered decoder for mimeType.

func (*SpanEngine) HandlesEncode

func (engine *SpanEngine) HandlesEncode(mimeType mimetype.MimeType) bool

Whether the SpanEngine has a registered encoder for mimeType.

func (*SpanEngine) JSONHandle

func (engine *SpanEngine) JSONHandle() *codec.JsonHandle

func (*SpanEngine) PickContentMimeType

func (engine *SpanEngine) PickContentMimeType(
	mimeType mimetype.MimeType, content interface{}, encoding bool,
) mimetype.MimeType

Picks the mimetype for encoding / decoding objects when source or target mimetype is unknown.

func (*SpanEngine) SetDecoder

func (engine *SpanEngine) SetDecoder(mimeType mimetype.MimeType, decoder Decoder)

Register a decoder for a given mimeType

func (*SpanEngine) SetEncoder

func (engine *SpanEngine) SetEncoder(mimeType mimetype.MimeType, encoder Encoder)

Register an encoder for a given mimeType

func (*SpanEngine) SetPassedEngine

func (engine *SpanEngine) SetPassedEngine(newEngine ContentEngine)

Change the engine passed into Encoder.Encode() and decoder.Decode()

func (*SpanEngine) SniffType

func (engine *SpanEngine) SniffType() bool

Whether SpanEngine will attempt to decode UNKNOWN content.

Jump to

Keyboard shortcuts

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