bzipper is a Rust crate for serialisation and deserialisation of binary streams.
See more at crates.io
.
Contrary to Serde/Bincode, the goal of this crate is to serialise data with a known size limit. Therefore, this crate may be more suited for networking or other cases where a fixed-sized buffer is needed.
Most primitive types serialise losslessly, with the exception being usize
and isize
. These serialise as u16
and u32
, respectively, for portability reasons.
Unsized types, such as str
and slices, are not supported. Instead, array should be used. For strings, the FixedString
type is also provided.
This crate revolves around the Serialise
and Deserialise
traits, both of which work around streams (more specifically, d-streams and s-streams).
Many core types come implemented with bzipper, including primitives as well as some standard library types such as Option
and Result
.
To serialise an object implementing Serialise
, simply allocate a so-called “s-stream” (short for serialisation stream) with the Sstream
type:
let mut buf: [u8; 16] = Default::default();
let mut stream = bzipper::Sstream::new(&mut buf);
The resulting stream is immutable in the sense that it cannot grow its buffer, altough it does keep track of the buffer's state.
A byte sequence can be added to our new stream by passing the stream to a call to the serialise
method:
use bzipper::Serialise;
let mut buf: [u8; 2] = Default::default();
let mut stream = bzipper::Sstream::new(&mut buf);
0x4554_u16.serialise(&mut stream).unwrap();
The ammount of bytes used by the serialiser (that is, the ammount of bytes written to the stream) is indicated by its return value (i.e. it has the type Result
).
Whilst the maximum ammount of bytes is specified by the SERIALISE_LIMIT
constant, this can in cases be lower (for example with None
variants which are always encoded as a single, null byte).
When serialising primitives, the resulting byte stream is in big endian (a.k.a. network endian). It is recommended for implementors to adhere to this convention as well.
After serialisation, the s-stream records the new write-to position of the buffer. This allows for chaining of serialisations, which can prove useful when implementing the trait for custom types.
As with serialisation, deserialisation uses streams (just with the Dstream
type; short for deserialisation stream):
let data = [0x45, 0x54];
let mut stream = bzipper::Dstream::new(&data);
Using these streams is also just as simple as with s-streams:
use bzipper::Deserialise;
let data = [0x45, 0x54];
let mut stream = bzipper::Dstream::new(&data);
assert_eq!(u16::deserialise(&mut stream).unwrap(), 0x4554);
When chaining serialisations, keep in mind that appropriate deserialisations should come in reverse order (streams function similarly to stacks in this sense).
Documentation is written in-source. See Docs.rs for a rendered instance.