Home

Awesome

lcs

Build Status codecov Go Report Card Codacy Badge

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.

Installation

$ go get -u github.com/coming-chat/lcs

Usage

import "github.com/coming-chat/lcs"

See example_test.go for complete examples.

Basic types

You can serialize and deserialize the following basic types:

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

Struct types

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)

Struct with optional fields

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"`
}

Fixed length lists

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

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},
})