Bebop

Bebop
Login

Bebop

Bebop is a simple and fast serialisation format. You write bebop schemas, and from these bop files different tools produce source code in a number of different languages for serialising and deserialising data to and from the bebop wire format.

This repo builds a tool that generates Go source code from bop files.

One way you could use this is:

  1. go get wellquite.org/bebop/cmd/bebop@latest
  2. Create your bop file, e.g. protocol.bop
  3. Alongside it, create a generate.go file, with the following content:

    package mypackage
    
    //go:generate go run wellquite.org/bebop/cmd/bebop -i ./protocol.bop -o ./protocol.go -p my/full/package/name/mypackage
    
  4. Then, whenever you do a go generate ./... in your project, this bebop tool will generate protocol.go from your protocol.bop schema definition.

What features are supported?

Basically everything I could figure out from the upstream documentation; apart from the readonly flag which can't really be implemented in Go.

Generated API

Imagine a bebop enum, struct, message or union, named Foo. This tool will generate the following API:

// EncodeBebop writes the value to the writer, serialized as Bebop.
func (*Foo) EncodeBebop(writer io.Writer) error

// DecodeBebop attempts to read Bebop from the reader and to
// deserialize it into the value.
func (*Foo) DecodeBebop(reader io.Reader) error

// MarshalBebop writes the value into the buf, serialized as
// Bebop. The slice of the buf written to is returned. If the buf is too
// small, a new buf is created, written to, and returned.
func (*Foo) MarshalBebop(buf []byte) ([]byte, error)

// UnmarshalBebop attempts to read Bebop from the buf and to
// deserialize it into the value.
func (*Foo) UnmarshalBebop(buf []byte) (int, error)

// SizeBebop returns the number of bytes this value uses when
// serialized to Bebop.
func (*Foo) SizeBebop() int

If you have specified an opcode, there will be:

// [opcode(653)]
func (*Foo) Opcode() uint32

Because I support imports, more functions must be public than one might like, because they may be needed by other generated code in other packages. All the functions that are not intended for public use have comments // Not intended for public use. and all those functions are named starting Bebop.