serialize
should be used to easily define serializable structs for your already existing data structures,
everything in native Go.
Table of contents
- Using Protobuf, FlatBuffers or other related tools are hard to set up or imply using a separate domain specific language (DSL)
- Using JSON or XML is not storage efficient
- Most of the existing solutions do not support Go polymorphism (using
interface{}
) - There is little flexibility when it comes to treating different fields in a different manner (for example, when serializing for hashing you would like to exclude the hash field itself)
- The standard way of serializing structures in Go is
gob
, but it is unintuitive to use and not suitable for processes like hashing (the output is very environment dependent)
- Serialize primitive types, user defined structures and arrays
- Serialize polymorphic fields (ie.
interface{}
) - Options for each struct field
- Multiple serializers interfaces with different options
- Runtime information kept only about
interface{}
fields, structure schema is kept directly in code
This is a short example of serialize
's main features.
package main
import "fmt"
//go:generate serialize -file=$GOFILE -type=Foo -serializer=hashing
type Foo struct {
Value int
Hash string `hashing:"ignore"` // This means that the "HashingSerializer" will ignore this field
Custom Bar
Poly interface{}
}
//go:generate serialize -file=$GOFILE -type=Bar -serializer=hashing
type Bar struct {
Value int
}
// This table declaration is needed only if you use interface{} fields in your structs
//go:generate serialize -file=$GOFILE -table=true
var TypeIdTable = map[string]uint16{
"Foo": 1,
"Bar": 2,
}
func main() {
foo := Foo{0, "this will be the hash", Bar{0}, Bar{1}}
// Default serializer
output, _ := foo.Serialize()
unserializedData, consumedBytes, _ := Foo{}.Unserialize(output)
newFoo := unserializedData.(Foo)
fmt.Printf("%v -> %v -> %v (%d bytes)\n", foo, output, newFoo, consumedBytes)
// Custom serializer that ignores the Hash field
output, _ = foo.HashingSerialize()
unserializedData, consumedBytes, _ = Foo{}.HashingUnserialize(output)
newFoo = unserializedData.(Foo)
fmt.Printf("%v -> %v -> %v (%d bytes)\n", foo, output, newFoo, consumedBytes)
}
// Interfaces for our custom serializer
type HashingSerializer interface {
HashingSerialize() ([]byte, error)
}
type HashingUnserializer interface {
HashingUnserialize([]byte) (interface{}, uint64, error)
}
- Support
map
- Support arrays of
interface{}
- Benchmarks for time/memory
- Better flow for polymorphism handling
If you find this library useful and you would like to share some thoughts or help developing it, drop me an email at mihailferaru2000@gmail.com
And don't forget to STAR it! 🌟