Convert Figma logo to code with AI

bincode-org logobincode

A binary encoder / decoder implementation in Rust.

2,639
265
2,639
30

Top Related Projects

8,997

Serialization framework for Rust

MessagePack implementation for Rust / msgpack.org[Rust]

Cap'n Proto for Rust

Quick Overview

Bincode is a binary serialization format for Rust. It's designed to be compact, fast, and deterministic, making it ideal for network protocols, file formats, and in-memory representations of data structures.

Pros

  • Fast serialization and deserialization
  • Compact binary format, reducing data size
  • Deterministic output, useful for hashing and comparing data
  • Seamless integration with Serde, Rust's popular serialization framework

Cons

  • Not human-readable like JSON or YAML
  • Limited cross-language support compared to more universal formats
  • May require additional steps for backward compatibility when evolving data structures
  • Not suitable for scenarios where data needs to be manually inspected or edited

Code Examples

Serializing a struct:

use serde::{Serialize, Deserialize};
use bincode;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct MyStruct {
    x: i32,
    y: String,
}

let my_struct = MyStruct { x: 5, y: "hello".to_string() };
let encoded: Vec<u8> = bincode::serialize(&my_struct).unwrap();

Deserializing data:

let decoded: MyStruct = bincode::deserialize(&encoded[..]).unwrap();
assert_eq!(my_struct, decoded);

Custom configuration:

use bincode::{config, Infinite};

let config = config::standard()
    .with_little_endian()
    .with_varint_encoding()
    .limit_data_len(1024);

let encoded = config.serialize(&my_struct).unwrap();

Getting Started

  1. Add bincode to your Cargo.toml:

    [dependencies]
    bincode = "1.3"
    serde = { version = "1.0", features = ["derive"] }
    
  2. In your Rust code:

    use serde::{Serialize, Deserialize};
    use bincode;
    
    #[derive(Serialize, Deserialize)]
    struct MyData {
        // Your data fields here
    }
    
    // Serialize
    let encoded: Vec<u8> = bincode::serialize(&my_data).unwrap();
    
    // Deserialize
    let decoded: MyData = bincode::deserialize(&encoded[..]).unwrap();
    

Competitor Comparisons

8,997

Serialization framework for Rust

Pros of serde

  • More versatile, supporting multiple serialization formats (JSON, YAML, TOML, etc.)
  • Extensive ecosystem with numerous integrations and extensions
  • Highly customizable with derive macros and attributes

Cons of serde

  • Slightly more complex to use due to its flexibility
  • May have a larger binary size when compiled, especially with multiple formats

Code Comparison

serde:

#[derive(Serialize, Deserialize)]
struct Point {
    x: i32,
    y: i32,
}

bincode:

#[derive(Encode, Decode)]
struct Point {
    x: i32,
    y: i32,
}

Key Differences

  • serde is a general-purpose serialization framework, while bincode focuses on binary serialization
  • bincode is more lightweight and specialized for binary format
  • serde requires separate serializer/deserializer crates for each format, bincode includes everything in one crate

Use Cases

  • serde: Projects requiring multiple serialization formats or complex data structures
  • bincode: Performance-critical applications with simple data structures, focusing on binary serialization

Community and Ecosystem

  • serde has a larger community and more third-party integrations
  • bincode is more focused but still well-maintained and actively developed

Performance

  • bincode generally offers better performance for binary serialization
  • serde's performance varies depending on the chosen format, but can be optimized for specific use cases

MessagePack implementation for Rust / msgpack.org[Rust]

Pros of msgpack-rust

  • Supports a wider range of data types, including custom types
  • Offers better interoperability with other languages and systems
  • Provides more flexible serialization options

Cons of msgpack-rust

  • Generally slower serialization and deserialization compared to bincode
  • Larger encoded size for most data structures
  • More complex API, potentially requiring more code to use effectively

Code Comparison

msgpack-rust:

use rmp_serde::{Serializer, Deserializer};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct MyStruct { /* ... */ }

let mut buf = Vec::new();
my_struct.serialize(&mut Serializer::new(&mut buf)).unwrap();
let deserialized: MyStruct = Deserialize::deserialize(&mut Deserializer::new(&buf[..])).unwrap();

bincode:

use bincode::{serialize, deserialize};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct MyStruct { /* ... */ }

let encoded: Vec<u8> = serialize(&my_struct).unwrap();
let decoded: MyStruct = deserialize(&encoded[..]).unwrap();

The code comparison shows that bincode offers a simpler API with fewer lines of code required for basic serialization and deserialization operations. However, msgpack-rust provides more control over the serialization process, which can be beneficial for complex use cases or when interoperability is a priority.

Cap'n Proto for Rust

Pros of Cap'n Proto Rust

  • Schema-based serialization with strong type safety
  • Supports zero-copy deserialization for improved performance
  • Offers advanced features like RPC and versioning

Cons of Cap'n Proto Rust

  • More complex setup and usage compared to Bincode
  • Larger binary size due to additional features
  • Steeper learning curve for developers new to the ecosystem

Code Comparison

Cap'n Proto Rust:

#[derive(Clone, Copy, Debug)]
pub struct Person<'a> {
    pub name: capnp::text::Reader<'a>,
    pub age: u32,
}

Bincode:

#[derive(Serialize, Deserialize, Debug)]
struct Person {
    name: String,
    age: u32,
}

Cap'n Proto Rust requires defining schemas separately and generating Rust code from them, while Bincode uses simple derive macros on standard Rust structs. Cap'n Proto offers more advanced features but at the cost of increased complexity, while Bincode provides a simpler, more straightforward approach to serialization and deserialization.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Bincode

CI

Matrix

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.
  • ajeetdsouza/zoxide: zoxide uses Bincode to store a database of directories and their access frequencies on disk.

Example

use bincode::{config, 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 = config::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
}

Specification

Bincode's format is specified in docs/spec.md.

FAQ

Is Bincode suitable for storage?

The encoding format is stable, 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 occurred.

Bincode 1 and 2 are completely compatible if the same configuration is used.

Bincode is invariant over byte-order, 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.

Is Bincode suitable for untrusted inputs?

Bincode attempts to protect against hostile data. There is a maximum size configuration available (Configuration::with_limit), 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.

What is Bincode's MSRV (minimum supported Rust version)?

Bincode 2.0 is still in development and does not yet have a targeted 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.

Why does bincode not respect #[repr(u8)]?

Bincode will encode enum variants as a u32. If you're worried about storage size, we can recommend enabling Configuration::with_variable_int_encoding(). This option is enabled by default with the standard configuration. In this case enum variants will almost always be encoded as a u8.

Currently we have not found a compelling case to respect #[repr(...)]. You're most likely trying to interop with a format that is similar-but-not-quite-bincode. We only support our own protocol (spec).

If you really want to use bincode to encode/decode a different protocol, consider implementing Encode and Decode yourself. bincode-derive will output the generated implementation in target/generated/bincode/<name>_Encode.rs and target/generated/bincode/<name>_Decode.rs which should get you started.