serix

package
v2.0.0-rc.1.0...-64c530f Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2023 License: Apache-2.0, BSD-2-Clause Imports: 18 Imported by: 0

Documentation

Overview

Package serix serializes and deserializes complex Go objects into/from bytes using reflection.

Structs serialization/deserialization

In order for a field to be detected by serix it must have `serix` struct tag set with the position index: `serix:"0"`. serix traverses all fields and handles them in the order specified in the struct tags. Apart from the required position you can provide the following settings to serix via struct tags: "optional" - means that field might be nil. Only valid for pointers or interfaces: `serix:"1,optional"` "lengthPrefixType=uint32" - provide serializer.SeriLengthPrefixType for that field: `serix:"2,lengthPrefixType=unint32"` "nest" - handle embedded/anonymous field as a nested field: `serix:"3,nest"` See serix_text.go for more detail.

Index

Constants

View Source
const (
	// LengthPrefixTypeAsByte defines a collection length to be denoted by a byte.
	LengthPrefixTypeAsByte = LengthPrefixType(serializer.SeriLengthPrefixTypeAsByte)
	// LengthPrefixTypeAsUint16 defines a collection length to be denoted by a uint16.
	LengthPrefixTypeAsUint16 = LengthPrefixType(serializer.SeriLengthPrefixTypeAsUint16)
	// LengthPrefixTypeAsUint32 defines a collection length to be denoted by a uint32.
	LengthPrefixTypeAsUint32 = LengthPrefixType(serializer.SeriLengthPrefixTypeAsUint32)
)

Variables

View Source
var DefaultAPI = NewAPI()

DefaultAPI is the default instance of the API type.

View Source
var (
	// ErrNonUTF8String gets returned when a non UTF-8 string is being encoded/decoded.
	ErrNonUTF8String = errors.New("non UTF-8 string value")
)

Functions

func DecodeHex

func DecodeHex(s string) ([]byte, error)

DecodeHex decodes the given hex string to bytes. It expects the 0x prefix.

func DecodeUint256

func DecodeUint256(s string) (*big.Int, error)

DecodeUint256 decodes the little-endian hex encoded string to an uint256.

func DecodeUint64

func DecodeUint64(s string) (uint64, error)

DecodeUint64 decodes the base 10 string to an uint64.

func EncodeHex

func EncodeHex(b []byte) string

EncodeHex encodes the bytes string to a hex string. It always adds the 0x prefix if bytes are not empty.

func EncodeUint256

func EncodeUint256(n *big.Int) string

EncodeUint256 encodes the uint256 to a little-endian encoded hex string.

func EncodeUint64

func EncodeUint64(n uint64) string

EncodeUint64 encodes the uint64 to a base 10 string.

Types

type API

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

API is the main object of the package that provides the methods for client to use. It holds all the settings and configuration. It also stores the cache. Most often you will need a single object of API for the whole program. You register all type settings and interfaces on the program start or in init() function. Instead of creating a new API object you can also use the default singleton API object: DefaultAPI.

func NewAPI

func NewAPI() *API

NewAPI creates a new instance of the API type.

func (*API) Decode

func (api *API) Decode(ctx context.Context, b []byte, obj interface{}, opts ...Option) (int, error)

Decode deserializes bytes b into the provided object obj. obj must be a non-nil pointer for serix to deserialize into it. serix traverses the object recursively and deserializes everything based on its type. If a type implements the custom Deserializable interface serix delegates the deserialization to that type. During the decoding process serix also performs the validation if such option was provided. Use the options list opts to customize the deserialization behavior.

func (*API) Encode

func (api *API) Encode(ctx context.Context, obj interface{}, opts ...Option) ([]byte, error)

Encode serializes the provided object obj into bytes. serix traverses the object recursively and serializes everything based on the type. If a type implements the custom Serializable interface serix delegates the serialization to that type. During the encoding process serix also performs the validation if such option was provided. Use the options list opts to customize the serialization behavior. To ensure deterministic serialization serix automatically applies lexical ordering for maps.

func (*API) JSONDecode

func (api *API) JSONDecode(ctx context.Context, data []byte, obj interface{}, opts ...Option) error

JSONDecode deserializes json data into the provided object obj.

func (*API) JSONEncode

func (api *API) JSONEncode(ctx context.Context, obj any, opts ...Option) ([]byte, error)

JSONEncode serializes the provided object obj into its JSON representation.

func (*API) MapDecode

func (api *API) MapDecode(ctx context.Context, m map[string]any, obj interface{}, opts ...Option) error

MapDecode deserializes generic map m into the provided object obj. obj must be a non-nil pointer for serix to deserialize into it. serix traverses the object recursively and deserializes everything based on its type. Use the options list opts to customize the deserialization behavior.

func (*API) MapEncode

func (api *API) MapEncode(ctx context.Context, obj interface{}, opts ...Option) (*orderedmap.OrderedMap, error)

MapEncode serializes the provided object obj into an ordered map. serix traverses the object recursively and serializes everything based on the type. Use the options list opts to customize the serialization behavior.

func (*API) RegisterInterfaceObjects

func (api *API) RegisterInterfaceObjects(iType interface{}, objs ...interface{}) error

RegisterInterfaceObjects tells serix that when it encounters iType during serialization/deserialization it actually might be one of the objs types. Those objs type must provide their ObjectTypes beforehand via API.RegisterTypeSettings(). serix needs object types to be able to figure out what concrete object to instantiate during the deserialization based on its object type code. In order for reflection to grasp the actual interface type, iType must be provided as a pointer to an interface: api.RegisterInterfaceObjects((*Interface)(nil), (*InterfaceImpl)(nil)) See TestMain() in serix_test.go for more detail.

func (*API) RegisterTypeSettings

func (api *API) RegisterTypeSettings(obj interface{}, ts TypeSettings) error

RegisterTypeSettings registers settings for a particular type obj. It's better to provide obj as a value, not a pointer, that way serix will be able to get the type settings for both values and pointers during Encode/Decode via dereferencing The settings provided via registration are considered global and default ones, they can be overridden by type settings parsed from struct tags or by type settings provided via option to the Encode/Decode methods. See TypeSettings for more detail.

func (*API) RegisterValidators

func (api *API) RegisterValidators(obj any, bytesValidatorFn func(context.Context, []byte) error, syntacticValidatorFn interface{}) error

RegisterValidators registers validator functions that serix will call during the Encode and Decode processes. There are two types of validator functions:

1. Syntactic validators, they validate the Go object and its data. For Encode they are called for the original Go object before serix serializes the object into bytes. For Decode they are called after serix builds the Go object from bytes.

2. Bytes validators, they validate the corresponding bytes representation of an object. For Encode they are called after serix serializes Go object into bytes For Decode they are called for the bytes before serix deserializes them into a Go object.

The validation is called for every registered type during the recursive traversal. It's an early stop process, if some validator returns an error serix stops the Encode/Decode and pops up the error.

obj is an instance of the type you want to provide the validator for. Note that it's better to pass the obj as a value, not as a pointer because that way serix would be able to dereference pointers during Encode/Decode and detect the validators for both pointers and values bytesValidatorFn is a function that accepts context.Context, []byte and returns an error. syntacticValidatorFn is a function that accepts context.Context, and an object with the same type as obj. Every validator func is optional, just provide nil. Example: bytesValidator := func(ctx context.Context, b []byte) error { ... } syntacticValidator := func (ctx context.Context, t time.Time) error { ... } api.RegisterValidators(time.Time{}, bytesValidator, syntacticValidator)

See TestMain() in serix_test.go for more examples.

type ArrayRules

type ArrayRules serializer.ArrayRules

ArrayRules defines rules around a to be deserialized array. Min and Max at 0 define an unbounded array.

type Deserializable

type Deserializable interface {
	Decode(b []byte) (int, error)
}

Deserializable is a type that can deserialize itself. Serix will call its .Decode() method instead of trying to deserialize it in the default way. The behavior is totally the same as in the standard "encoding/json" package and json.Unmarshaler interface.

type DeserializableJSON

type DeserializableJSON interface {
	DecodeJSON(b any) error
}

DeserializableJSON is a type that can deserialize itself from JSON format. Serix will call its .Decode() method instead of trying to deserialize it in the default way. The behavior is totally the same as in the standard "encoding/json" package and json.Unmarshaler interface.

type LengthPrefixType

type LengthPrefixType serializer.SeriLengthPrefixType

LengthPrefixType defines the type of the value denoting the length of a collection.

type Option

type Option func(o *options)

Option is an option for Encode/Decode methods.

func WithTypeSettings

func WithTypeSettings(ts TypeSettings) Option

WithTypeSettings returns an option that sets TypeSettings. TypeSettings provided via option override global TypeSettings from the registry. See TypeSettings for details.

func WithValidation

func WithValidation() Option

WithValidation returns an Option that tells serix to perform validation.

type Serializable

type Serializable interface {
	Encode() ([]byte, error)
}

Serializable is a type that can serialize itself. Serix will call its .Encode() method instead of trying to serialize it in the default way. The behavior is totally the same as in the standard "encoding/json" package and json.Marshaler interface.

type SerializableJSON

type SerializableJSON interface {
	EncodeJSON() (any, error)
}

SerializableJSON is a type that can serialize itself to JSON format. Serix will call its .EncodeJSON() method instead of trying to serialize it in the default way. The behavior is totally the same as in the standard "encoding/json" package and json.Marshaler interface.

type TypeSettings

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

TypeSettings holds various settings for a particular type. Those settings determine how the object should be serialized/deserialized. There are three way to provide TypeSettings 1. Via global registry: API.RegisterTypeSettings(). 2. Parse from struct tags. 3. Pass as an option to API.Encode/API.Decode methods. The type settings provided via struct tags or an option override the type settings from the registry. So the precedence is the following 1<2<3. See API.RegisterTypeSettings() and WithTypeSettings() for more detail.

func (TypeSettings) ArrayRules

func (ts TypeSettings) ArrayRules() *ArrayRules

ArrayRules returns serializer.ArrayRules.

func (TypeSettings) LengthPrefixType

func (ts TypeSettings) LengthPrefixType() (LengthPrefixType, bool)

LengthPrefixType returns LengthPrefixType.

func (TypeSettings) LexicalOrdering

func (ts TypeSettings) LexicalOrdering() (val bool, set bool)

LexicalOrdering returns lexical ordering flag.

func (TypeSettings) MapKey

func (ts TypeSettings) MapKey() (string, bool)

MapKey returns the map key name.

func (TypeSettings) MaxLen

func (ts TypeSettings) MaxLen() (uint, bool)

MaxLen returns max length for the object.

func (TypeSettings) MinLen

func (ts TypeSettings) MinLen() (uint, bool)

MinLen returns min length for the object.

func (TypeSettings) MinMaxLen

func (ts TypeSettings) MinMaxLen() (int, int)

MinMaxLen returns min/max lengths for the object. Returns 0 for either value if they are not set.

func (TypeSettings) MustMapKey

func (ts TypeSettings) MustMapKey() string

MustMapKey must return a map key name.

func (TypeSettings) ObjectType

func (ts TypeSettings) ObjectType() interface{}

ObjectType returns the object type as an uint8 or uint32 number.

func (TypeSettings) WithArrayRules

func (ts TypeSettings) WithArrayRules(rules *ArrayRules) TypeSettings

WithArrayRules specifies serializer.ArrayRules.

func (TypeSettings) WithLengthPrefixType

func (ts TypeSettings) WithLengthPrefixType(lpt LengthPrefixType) TypeSettings

WithLengthPrefixType specifies LengthPrefixType.

func (TypeSettings) WithLexicalOrdering

func (ts TypeSettings) WithLexicalOrdering(val bool) TypeSettings

WithLexicalOrdering specifies whether the type must be lexically ordered during serialization.

func (TypeSettings) WithMapKey

func (ts TypeSettings) WithMapKey(name string) TypeSettings

WithMapKey specifies the name for the map key.

func (TypeSettings) WithMaxLen

func (ts TypeSettings) WithMaxLen(l uint) TypeSettings

WithMaxLen specifies the max length for the object.

func (TypeSettings) WithMinLen

func (ts TypeSettings) WithMinLen(l uint) TypeSettings

WithMinLen specifies the min length for the object.

func (TypeSettings) WithObjectType

func (ts TypeSettings) WithObjectType(t interface{}) TypeSettings

WithObjectType specifies the object type. It can be either uint8 or uint32 number. The object type holds two meanings: the actual code (number) and the serializer.TypeDenotationType like uint8 or uint32. serix uses object type to actually encode the number and to know its serializer.TypeDenotationType to be able to decode it.

Jump to

Keyboard shortcuts

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