112 lines
4.7 KiB
Markdown
112 lines
4.7 KiB
Markdown
|
# Bincode
|
||
|
|
||
|
<img align="right" src="./logo.png" />
|
||
|
|
||
|

|
||
|
[](https://crates.io/crates/bincode)
|
||
|
[](https://opensource.org/licenses/MIT)
|
||
|
[](https://blog.rust-lang.org/2017/06/08/Rust-1.18.html)
|
||
|
|
||
|
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](https://github.com/alexcrichton/flate2-rs) compression
|
||
|
library.
|
||
|
|
||
|
## [API Documentation](https://docs.rs/bincode/)
|
||
|
|
||
|
## Bincode in the wild
|
||
|
|
||
|
* [google/tarpc](https://github.com/google/tarpc): Bincode is used to serialize and deserialize networked RPC messages.
|
||
|
* [servo/webrender](https://github.com/servo/webrender): Bincode records webrender API calls for record/replay-style graphics debugging.
|
||
|
* [servo/ipc-channel](https://github.com/servo/ipc-channel): IPC-Channel uses Bincode to send structs between processes using a channel-like API.
|
||
|
|
||
|
## Example
|
||
|
|
||
|
```rust
|
||
|
use serde::{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> = bincode::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 = bincode::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.
|
||
|
|
||
|
## Specification
|
||
|
|
||
|
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:
|
||
|
|
||
|
### Is Bincode suitable for storage?
|
||
|
|
||
|
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.
|
||
|
|
||
|
### Is Bincode suitable for untrusted inputs?
|
||
|
|
||
|
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.
|
||
|
|
||
|
### What is Bincode's MSRV (minimum supported Rust version)?
|
||
|
|
||
|
Bincode 1.0 maintains support for rust 1.18.0. Any changes to this are considered a breaking change for semver purposes.
|