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
- Variables
- func DecodeHex(s string) ([]byte, error)
- func DecodeUint256(s string) (*big.Int, error)
- func DecodeUint64(s string) (uint64, error)
- func EncodeHex(b []byte) string
- func EncodeUint256(n *big.Int) string
- func EncodeUint64(n uint64) string
- type API
- func (api *API) Decode(ctx context.Context, b []byte, obj interface{}, opts ...Option) (int, error)
- func (api *API) Encode(ctx context.Context, obj interface{}, opts ...Option) ([]byte, error)
- func (api *API) JSONDecode(ctx context.Context, data []byte, obj interface{}, opts ...Option) error
- func (api *API) JSONEncode(ctx context.Context, obj any, opts ...Option) ([]byte, error)
- func (api *API) MapDecode(ctx context.Context, m map[string]any, obj interface{}, opts ...Option) error
- func (api *API) MapEncode(ctx context.Context, obj interface{}, opts ...Option) (*orderedmap.OrderedMap, error)
- func (api *API) RegisterInterfaceObjects(iType interface{}, objs ...interface{}) error
- func (api *API) RegisterTypeSettings(obj interface{}, ts TypeSettings) error
- func (api *API) RegisterValidators(obj any, bytesValidatorFn func(context.Context, []byte) error, ...) error
- type ArrayRules
- type Deserializable
- type LengthPrefixType
- type Option
- type Serializable
- type TypeSettings
- func (ts TypeSettings) ArrayRules() *ArrayRules
- func (ts TypeSettings) LengthPrefixType() (LengthPrefixType, bool)
- func (ts TypeSettings) LexicalOrdering() (val bool, set bool)
- func (ts TypeSettings) MapKey() (string, bool)
- func (ts TypeSettings) MaxLen() (uint64, bool)
- func (ts TypeSettings) MinLen() (uint64, bool)
- func (ts TypeSettings) MinMaxLen() (int, int)
- func (ts TypeSettings) MustMapKey() string
- func (ts TypeSettings) ObjectType() interface{}
- func (ts TypeSettings) WithArrayRules(rules *ArrayRules) TypeSettings
- func (ts TypeSettings) WithLengthPrefixType(lpt LengthPrefixType) TypeSettings
- func (ts TypeSettings) WithLexicalOrdering(val bool) TypeSettings
- func (ts TypeSettings) WithMapKey(name string) TypeSettings
- func (ts TypeSettings) WithMaxLen(l uint64) TypeSettings
- func (ts TypeSettings) WithMinLen(l uint64) TypeSettings
- func (ts TypeSettings) WithObjectType(t interface{}) TypeSettings
Constants ¶
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 ¶
var DefaultAPI = NewAPI()
DefaultAPI is the default instance of the API type.
var ( // ErrNonUTF8String gets returned when a non UTF-8 string is being encoded/decoded. ErrNonUTF8String = errors.New("non UTF-8 string value") )
Functions ¶
func DecodeUint256 ¶
DecodeUint256 decodes the little-endian hex encoded string to an uint256.
func DecodeUint64 ¶
DecodeUint64 decodes the base 10 string to an uint64.
func EncodeHex ¶
EncodeHex encodes the bytes string to a hex string. It always adds the 0x prefix if bytes are not empty.
func EncodeUint256 ¶
EncodeUint256 encodes the uint256 to a little-endian encoded hex string.
func EncodeUint64 ¶
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 (*API) Decode ¶
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 ¶
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 behaviour. To ensure deterministic serialization serix automatically applies lexical ordering for maps.
func (*API) JSONDecode ¶
JSONDecode deserializes json data into the provided object obj.
func (*API) JSONEncode ¶
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 behaviour.
func (*API) RegisterInterfaceObjects ¶
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 ¶
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 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 ¶
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 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() (uint64, bool)
MaxLen returns max length for the object.
func (TypeSettings) MinLen ¶
func (ts TypeSettings) MinLen() (uint64, 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 uint64) TypeSettings
WithMaxLen specifies the max length for the object.
func (TypeSettings) WithMinLen ¶
func (ts TypeSettings) WithMinLen(l uint64) 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.