Before history rewrite
Go to file
David Tolnay 65f87aefd4 Bump byteorder requirement to 1.3.0
1.3.0 is the first version that performs auto detection of i128 support,
which we rely on.
2019-02-16 11:33:31 -08:00
examples 2nd implementation of the Config Trait (#214) 2018-02-07 18:26:46 -08:00
src Define html_root_url 2019-02-16 11:28:17 -08:00
tests Make i128 support automatic for supporting Rustc versions 2019-01-28 09:59:18 -05:00
.gitignore rename doc functions (#208) 2017-10-10 16:41:27 -07:00
.travis.yml Remove CI for unused i128 feature 2019-02-16 11:29:18 -08:00
Cargo.toml Bump byteorder requirement to 1.3.0 2019-02-16 11:33:31 -08:00
LICENSE.md Update LICENSE.md 2014-09-18 13:30:55 -07:00
README.md Update README example to match #214 changes (#228) 2018-02-26 09:51:28 -08:00
build.rs Make i128 support automatic for supporting Rustc versions 2019-01-28 09:59:18 -05:00
changelist.org capitalize Bincode 2017-10-13 17:38:36 -07:00
logo.png add logo 2015-02-15 12:36:44 -08:00

README.md

Bincode

Build Status

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.

Api Documentation

Bincode in the wild

  • 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.

Example

#[macro_use]
extern crate serde_derive;
extern crate bincode;

use bincode::{serialize, deserialize};

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Entity {
    x: f32,
    y: f32,
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct World(Vec<Entity>);

fn main() {
    let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);

    let encoded: Vec<u8> = serialize(&world).unwrap();

    // 8 bytes for the length of the vector, 4 bytes per float.
    assert_eq!(encoded.len(), 8 + 4 * 4);

    let decoded: World = deserialize(&encoded[..]).unwrap();

    assert_eq!(world, decoded);
}

Details

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 as i64/u64, for portability.
  • enums variants are encoded as a u32 instead of a usize. u32 is enough for all practical uses.
  • str is encoded as (u64, &[u8]), where the u64 is the number of bytes contained in the encoded string.