rmp/lib.rs
1//! # The Rust MessagePack Library
2//!
3//! RMP is a pure Rust [MessagePack](http://msgpack.org) implementation of an efficient binary
4//! serialization format. This crate provides low-level core functionality, writers and readers for
5//! primitive values with direct mapping between binary MessagePack format.
6//!
7//! **Warning** this library is still in rapid development and everything may change until 1.0
8//! comes.
9//!
10//! ## Usage
11//!
12//! To use `rmp`, first add this to your `Cargo.toml`:
13//!
14//! ```toml
15//! [dependencies.rmp]
16//! rmp = "^0.8"
17//! ```
18//!
19//! Then, add this line to your crate root:
20//!
21//! ```rust
22//! extern crate rmp;
23//! ```
24//!
25//! ## Features
26//!
27//! - **Convenient API**
28//!
29//! RMP is designed to be lightweight and straightforward. There are low-level API, which gives you
30//! full control on data encoding/decoding process and makes no heap allocations. On the other hand
31//! there are high-level API, which provides you convenient interface using Rust standard library and
32//! compiler reflection, allowing to encode/decode structures using `derive` attribute.
33//!
34//! - **Zero-copy value decoding**
35//!
36//! RMP allows to decode bytes from a buffer in a zero-copy manner easily and blazingly fast, while Rust
37//! static checks guarantees that the data will be valid until buffer lives.
38//!
39//! - **Clear error handling**
40//!
41//! RMP's error system guarantees that you never receive an error enum with unreachable variant.
42//!
43//! - **Robust and tested**
44//!
45//! This project is developed using TDD and CI, so any found bugs will be fixed without breaking
46//! existing functionality.
47//!
48//! ## Detailed
49//!
50//! This crate represents the very basic functionality needed to work with MessagePack format.
51//! Ideologically it is developed as a basis for building high-level abstractions.
52//!
53//! Currently there are two large modules: encode and decode. More detail you can find in the
54//! corresponding sections.
55//!
56//! Formally every MessagePack message consists of some marker encapsulating a data type and the
57//! data itself. Sometimes there are no separate data chunk, for example for booleans. In these
58//! cases a marker contains the value. For example, the `true` value is encoded as `0xc3`.
59//!
60//! ```
61//! let mut buf = Vec::new();
62//! rmp::encode::write_bool(&mut buf, true).unwrap();
63//!
64//! assert_eq!([0xc3], buf[..]);
65//! ```
66//!
67//! Sometimes a single value can be encoded in multiple ways. For example a value of `42` can be
68//! represented as: `[0x2a], [0xcc, 0x2a], [0xcd, 0x00, 0x2a]` and so on, and all of them are
69//! considered as valid representations. To allow fine-grained control over encoding such values
70//! the library provides direct mapping functions.
71//!
72//! ```
73//! let mut bufs = vec![vec![]; 5];
74//!
75//! rmp::encode::write_pfix(&mut bufs[0], 42).unwrap();
76//! rmp::encode::write_u8(&mut bufs[1], 42).unwrap();
77//! rmp::encode::write_u16(&mut bufs[2], 42).unwrap();
78//! rmp::encode::write_u32(&mut bufs[3], 42).unwrap();
79//! rmp::encode::write_u64(&mut bufs[4], 42).unwrap();
80//!
81//! assert_eq!([0x2a], bufs[0][..]);
82//! assert_eq!([0xcc, 0x2a], bufs[1][..]);
83//! assert_eq!([0xcd, 0x00, 0x2a], bufs[2][..]);
84//! assert_eq!([0xce, 0x00, 0x00, 0x00, 0x2a], bufs[3][..]);
85//! assert_eq!([0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a], bufs[4][..]);
86//! ```
87//!
88//! But they aren't planned to be widely used. Instead we often need to encode bytes compactly to
89//! save space. In these cases RMP provides functions that guarantee that for encoding the most
90//! compact representation will be chosen.
91//!
92//! ```
93//! let mut buf = Vec::new();
94//!
95//! rmp::encode::write_sint(&mut buf, 300).unwrap();
96//!
97//! assert_eq!([0xcd, 0x1, 0x2c], buf[..]);
98//! ```
99//!
100//! On the other hand for deserialization it is not matter in which representation the value is
101//! encoded - RMP deals with all of them.
102//!
103//! Sometimes you know the exact type representation and want to enforce the deserialization process
104//! to make it strongly type safe.
105//!
106//! ```
107//! let buf = [0xcd, 0x1, 0x2c];
108//!
109//! assert_eq!(300, rmp::decode::read_u16(&mut &buf[..]).unwrap());
110//! ```
111//!
112//! However if you try to decode such bytearray as other integer type, for example `u32`, there will
113//! be type mismatch error.
114//!
115//! ```
116//! let buf = [0xcd, 0x1, 0x2c];
117//! rmp::decode::read_u32(&mut &buf[..]).err().unwrap();
118//! ```
119//!
120//! But sometimes all you want is just to encode an integer that *must* fit in the specified type
121//! no matter how it was encoded. RMP provides [`such`][read_int] function to ease integration with
122//! other MessagePack libraries.
123//!
124//! ```
125//! let buf = [0xcd, 0x1, 0x2c];
126//!
127//! assert_eq!(300i16, rmp::decode::read_int(&mut &buf[..]).unwrap());
128//! assert_eq!(300i32, rmp::decode::read_int(&mut &buf[..]).unwrap());
129//! assert_eq!(300i64, rmp::decode::read_int(&mut &buf[..]).unwrap());
130//! assert_eq!(300u16, rmp::decode::read_int(&mut &buf[..]).unwrap());
131//! assert_eq!(300u32, rmp::decode::read_int(&mut &buf[..]).unwrap());
132//! assert_eq!(300u64, rmp::decode::read_int(&mut &buf[..]).unwrap());
133//! ```
134//!
135//! ## API
136//!
137//! Almost all API are represented as pure functions, which accepts a generic `Write` or `Read` and
138//! the value to be encoded/decoded. For example let's do a round trip for π number.
139//!
140//! ```
141//! let pi = std::f64::consts::PI;
142//! let mut buf = Vec::new();
143//! rmp::encode::write_f64(&mut buf, pi).unwrap();
144//!
145//! assert_eq!([0xcb, 0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18], buf[..]);
146//! assert_eq!(pi, rmp::decode::read_f64(&mut &buf[..]).unwrap());
147//! ```
148//!
149//! [read_int]: decode/fn.read_int.html
150
151extern crate byteorder;
152extern crate num_traits;
153
154mod marker;
155pub mod encode;
156pub mod decode;
157
158pub use marker::Marker;
159
160/// Version of the MessagePack [spec](http://github.com/msgpack/msgpack/blob/master/spec.md).
161pub const MSGPACK_VERSION: u32 = 5;