cbor-gen
is a code generation tool that automatically creates CBOR (Concise Binary Object Representation) marshaling and unmarshaling functions for Go types.
The library generates MarshalCBOR
and UnmarshalCBOR
methods for your Go structs and types, allowing them to be encoded to and decoded from CBOR format. This is particularly useful when you need efficient binary serialization with CBOR support.
- Define your types in a .go file:
type MyStruct struct {
Field1 string
Field2 uint64
Field3 []byte
Field4 *CustomType
}
- Create a generator file (e.g.,
gen/main.go
):
package main
import (
cbg "github.com/whyrusleeping/cbor-gen"
)
func main() {
// Generate tuple-style encoders (list of fields)...
if err := cbg.WriteTupleEncodersToFile("cbor_gen.go", "mypackage",
MyStruct{},
// Add other types here...
); err != nil {
panic(err)
}
// Or generate map-style encoders (map of field names to field values)...
if err := cbg.WriteMapEncodersToFile("cbor_map_gen.go", "mypackage",
MyStruct{},
// Add other types here...
); err != nil {
panic(err)
}
}
- Run the generator:
go run gen/main.go
- Tuple encoding (
WriteTupleEncodersToFile
): Encodes structs as CBOR arrays, more space-efficient but order-dependent. - Map encoding (
WriteMapEncodersToFile
): Encodes structs as CBOR maps with field names, more verbose but order-independent.
The library supports several struct tags to customize encoding:
type Example struct {
// Rename field in CBOR output
Field1 string `cborgen:"renamed_field"`
// Preserve nil slices (encode nil as null, not as an empty cbor list)
Field2 []uint64 `cborgen:"preservenil"`
// Skip encoding this field when it matches its zero value. This is only applicable
// when map-encoding; when tuple-encoding, all fields are always written.
Field3 string `cborgen:"omitempty"`
// Set constant value XXX WTF IS THIS?
Field4 string `cborgen:"const=somevalue"`
// Maximum length for slices/strings, defaults to 8192 for lists,
// 2MiB for strings/bytes unless otherwise specified in cbg.Gen.
Field5 []byte `cborgen:"maxlen=1000000"`
// Allow this field to be missing when decoding a tuple-style struct. Optional fields
// may only appear at the end of of structs and cannot be followed by mandatory fields.
//
// This tag is ignored when decoding map-style structs as all fields are optional in
// map-style structs.
Field6 string `cborgen:"optional"`
}
Additionally, you can specify that struct with a single field should be encoded as that field alone as if it didn't appear in a struct by specifying the "transparent"
tag. For example, the following TransparentExample
will encode as a string (regardless of whether tuple or map encoding was specified when generating the UnmarshalCBOR
and MarshalCBOR
functions):
type TransparentExample struct {
TheOneAndOnlyField string `cborgen:"transparent"`
}
When working with map-encoded types, all fields are optional when decoding (they default to the field's zero-value) and unknown fields are skipped.
When working with tuple-encoded types, fields are mandatory by default and unknown (additional) fields will be rejected. However, it's possible to add additional optional fields to the end of the tuple-encoded struct by tagging them as cborgen:"optional"
; this makes it possible to decode a tuple-encoded struct that omits a suffix of the expected fields. On encoding, optional fields will always be included.
You can customize generation parameters using the Gen
type:
err := cbg.Gen{
MaxArrayLength: 8192, // Maximum length for arrays
MaxByteLength: 2<<20, // Maximum length for byte slices
MaxStringLength: 2<<20, // Maximum length for strings
}.WriteTupleEncodersToFile("cbor_gen.go", "mypackage",
MyType{},
)
The library can generate encoders/decoders for:
- Basic Go types (integers, strings, etc.)
- Slices, arrays, and maps.
- Custom types that implement
UnmarshalCBOR
andMarshalCBOR
(usually generated with this library). cid.Cid
from github.com/ipfs/go-cidbig.Int
The tool will generate MarshalCBOR(w io.Writer) error
and UnmarshalCBOR(r io.Reader) error
methods for each type. These methods handle the CBOR encoding and decoding respectively.
MIT