A compact encoder / decoder pair that uses a binary zero-fluff encoding scheme. The size of the encoded object will be the same or smaller than the size that the object takes up in memory in a running Rust program.
In addition to exposing two simple functions
(one that encodes to Vec<u8>
, and one that decodes from &[u8]
),
binary-encode exposes a Reader/Writer API that makes it work
perfectly with other stream-based APIs such as Rust files, network streams,
and the flate2-rs compression
library.
- google/tarpc: Bincode is used to serialize and deserialize networked RPC messages.
- servo/webrender: Bincode records WebRender API calls for record/replay-style graphics debugging.
- servo/ipc-channel: IPC-Channel uses Bincode to send structs between processes using a channel-like API.
use bincode::{config::Configuration, Decode, Encode};
#[derive(Encode, Decode, PartialEq, Debug)]
struct Entity {
x: f32,
y: f32,
}
#[derive(Encode, Decode, PartialEq, Debug)]
struct World(Vec<Entity>);
fn main() {
let config = Configuration::standard();
let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);
let encoded: Vec<u8> = bincode::encode_to_vec(&world, config).unwrap();
// The length of the vector is encoded as a varint u64, which in this case gets collapsed to a single byte
// See the documentation on varint for more info for that.
// The 4 floats are encoded in 4 bytes each.
assert_eq!(encoded.len(), 1 + 4 * 4);
let (decoded, len): (World, usize) = bincode::decode_from_slice(&encoded[..], config).unwrap();
assert_eq!(world, decoded);
assert_eq!(len, encoded.len()); // read all bytes
}
The encoding (and thus decoding) proceeds unsurprisingly -- primitive
types are encoded according to the underlying Writer
, tuples and
structs are encoded by encoding their fields one-by-one, and enums are
encoded by first writing out the tag representing the variant and
then the contents.
However, there are some implementation details to be aware of:
isize
/usize
are encoded asi64
/u64
, for portability.- enums variants are encoded as a
u32
instead of ausize
.u32
is enough for all practical uses. str
is encoded as(u64, &[u8])
, where theu64
is the number of bytes contained in the encoded string.
Bincode's format will eventually be codified into a specification, along with its configuration options and default configuration. In the meantime, here are some frequently asked questions regarding use of the crate:
The encoding format is stable across minor revisions, provided the same configuration is used. This should ensure that later versions can still read data produced by a previous versions of the library if no major version change has occured.
Bincode is invariant over byte-order in the default configuration
(bincode::options::DefaultOptions
), making an exchange between different
architectures possible. It is also rather space efficient, as it stores no
metadata like struct field names in the output format and writes long streams of
binary data without needing any potentially size-increasing encoding.
As a result, Bincode is suitable for storing data. Be aware that it does not implement any sort of data versioning scheme or file headers, as these features are outside the scope of this crate.
Bincode attempts to protect against hostile data. There is a maximum size
configuration available (bincode::config::Bounded
), but not enabled in the
default configuration. Enabling it causes pre-allocation size to be limited to
prevent against memory exhaustion attacks.
Deserializing any incoming data will not cause undefined behavior or memory issues, assuming that the deserialization code for the struct is safe itself.
Bincode can be used for untrusted inputs in the sense that it will not create a security issues in your application, provided the configuration is changed to enable a maximum size limit. Malicious inputs will fail upon deserialization.
Bincode 2.0 is still in development and does not yet have a targetted MSRV. Once 2.0 is fully released the MSRV will be locked. After this point any changes to the MSRV are considered a breaking change for semver purposes.