Go library for Libra canonical serialization (and deserialization). See LCS Spec.
For types defined and used in actual Libra blockchain, please visit go-libra: Libra client library with crypto verifications.
Supported Custom Marshal
& Unmarshal
.
$ go get -u github.com/coming-chat/lcs
import "github.com/coming-chat/lcs"
See example_test.go
for complete examples.
You can serialize and deserialize the following basic types:
- bool
- int8, int16, int32, int64, uint8, uint16, uint32, uint64
- string
- slice, map
bytes, _ := lcs.Marshal("hello")
fmt.Printf("%x\n", bytes)
// Output: 050000068656c6c6f
myInt := int16(0)
lcs.Unmarshal([]byte{0x05, 0x00}, &myInt) // <- be careful to pass a pointer
fmt.Printf("%d\n", myInt)
// Output: 5
Simple struct can be serialized or deserialized directly. You can use struct field tags to change lcs behaviors.
type MyStruct struct {
Boolean bool
Bytes []byte
Label string `lcs:"-"` // "-" tagged field is ignored
unexported uint32 // unexported field is ignored
}
// Serialize:
bytes, err := lcs.Marshal(&MyStruct{})
// Deserialize:
out := &MyStruct{}
err = lcs.Unmarshal(bytes, out)
Optional fields should be pointers, slices or maps with "optional" tag.
type MyStruct struct {
Label *string `lcs:"optional"`
Nested *MyStruct `lcs:"optional"`
Slice []byte `lcs:"optional"`
Map map[uint8]uint8 `lcs:"optional"`
}
Arrays are treated as fixed length lists.
You can also specify fixed length for struct members with len
tag. Slices and strings are supported.
type MyStruct struct {
Str string `lcs:"len=2"`
Bytes []byte `lcs:"len=4"`
OptionalBytes []byte `lcs:"len=4,optional"`
}
Enum types are golang interfaces.
(The old enum API is deprecated.)
// Enum1 is an enum type.
type Enum1 interface {
// isEnum1() // optional: member functions
}
// *Enum1Opt0, Enum1Opt1, Enum1Opt2 are variants of Enum1
type Enum1Opt0 struct {
Data uint32
}
type Enum1Opt1 struct{} // Use empty struct for a variant without contents.
type Enum1Opt2 []Enum1 // self reference is OK
// Register Enum1 with LCS. Will be available globaly.
var _ = lcs.RegisterEnum(
// nil pointer to the enum interface type:
(*Enum1)(nil),
// zero-values of each variants
(*Enum1Opt0)(nil), // Use pointer for non-empty struct.
Enum1Opt1{},
Enum1Opt2(nil),
)
// Usage: Marshal the enum alone, must use pointer
e1 := Enum1(Enum1Opt1{})
bytes, err := lcs.Marshal(&e1)
// Use Enum1 within other structs
type Wrapper struct {
Enum Enum1
}
bytes, err := lcs.Marshal(&Wrapper{
Enum: Enum1Opt0{10},
})