compact_encoding/
lib.rs

1#![forbid(unsafe_code, missing_docs)]
2#![cfg_attr(test, deny(warnings))]
3#![doc(test(attr(deny(warnings))))]
4
5//! # Series of compact encoding schemes for building small and fast parsers and serializers
6//!
7//! Binary compatible with the
8//! [original Javascript compact-encoding library](https://github.com/compact-encoding/compact-encoding/).
9//!
10//! ## Usage
11//!
12//! ### Basic
13//!
14//! Using only the types implemented here (replace `unwrap()` with proper
15//! handling of [EncodingError]):
16//!
17//! ```
18//! use compact_encoding::{CompactEncoding, State};
19//!
20//! // Start with an empty state
21//! let mut enc_state = State::new();
22//!
23//! let number = 41_u32;
24//! let str = "hi".to_string();
25//!
26//! // Use preencode to figure out how big a buffer is needed
27//! enc_state.preencode(&number).unwrap();
28//! enc_state.preencode(&str).unwrap();
29//!
30//! // Create buffer of pre-encoded size
31//! let mut buffer = enc_state.create_buffer();
32//! assert_eq!(buffer.len(), 1 + 1 + 2);
33//!
34//! // Then actually encode the values
35//! enc_state.encode(&number, &mut buffer).unwrap();
36//! enc_state.encode(&str, &mut buffer).unwrap();
37//! assert_eq!(buffer.to_vec(), vec![41_u8, 2_u8, b'h', b'i']);
38//!
39//! // On the decoding end, create a state from byte buffer
40//! let mut dec_state = State::from_buffer(&buffer);
41//! let number_dec: u32 = dec_state.decode(&buffer).unwrap();
42//! let str_dec: String = dec_state.decode(&buffer).unwrap();
43//! assert_eq!(number_dec, number);
44//! assert_eq!(str_dec, str);
45//! ```
46//!
47//! ### Custom
48//!
49//! If you want to encode your own structs directly, you can do that
50//! by implementing [CompactEncoding] yourself (replace `unwrap()` with proper
51//! handling of [EncodingError]):
52//!
53//! ```
54//! use compact_encoding::{CompactEncoding, EncodingError, State};
55//!
56//! #[derive(Debug, PartialEq)]
57//! struct MyStruct {
58//!     my_flag_1: bool,
59//!     my_flag_2: bool,
60//!     my_values: Vec<[u8; 32]>,
61//! }
62//!
63//! impl CompactEncoding<MyStruct> for State {
64//!     fn preencode(&mut self, value: &MyStruct) -> Result<usize, EncodingError> {
65//!         self.add_end(1)?; // flags
66//!         if !value.my_values.is_empty() {
67//!             self.preencode(&value.my_values)?;
68//!         }
69//!         Ok(self.end())
70//!     }
71//!
72//!     fn encode(&mut self, value: &MyStruct, buffer: &mut [u8]) -> Result<usize, EncodingError> {
73//!         let mut flags: u8 = 0;
74//!         if value.my_flag_1 {
75//!             flags |= 1;
76//!         }
77//!         if value.my_flag_2 {
78//!             flags |= 2;
79//!         }
80//!         if !value.my_values.is_empty() {
81//!             flags |= 4;
82//!         }
83//!         self.encode(&flags, buffer)?;
84//!         if !value.my_values.is_empty() {
85//!             self.encode(&value.my_values, buffer)?;
86//!         }
87//!         Ok(self.start())
88//!     }
89//!
90//!     fn decode(&mut self, buffer: &[u8]) -> Result<MyStruct, EncodingError> {
91//!        let flags: u8 = self.decode(buffer)?;
92//!        let my_flag_1: bool = flags & 1 != 0;
93//!        let my_flag_2: bool = flags & 2 != 0;
94//!        let my_values: Vec<[u8; 32]> = if flags & 4 != 0 {
95//!            self.decode(buffer)?
96//!        } else {
97//!            vec![]
98//!        };
99//!        Ok(MyStruct {
100//!             my_flag_1,
101//!             my_flag_2,
102//!             my_values
103//!        })
104//!     }
105//! }
106//!
107//! // Test values
108//! let empty = MyStruct {
109//!     my_flag_1: false,
110//!     my_flag_2: true,
111//!     my_values: vec![]
112//! };
113//! let non_empty = MyStruct {
114//!     my_flag_1: true,
115//!     my_flag_2: false,
116//!     my_values: vec![[1; 32], [2; 32]]
117//! };
118//!
119//! // Start with an empty state
120//! let mut enc_state = State::new();
121//! enc_state.preencode(&empty).unwrap();
122//! enc_state.preencode(&non_empty).unwrap();
123//! let mut buffer = enc_state.create_buffer();
124//!
125//! // With the above use of a flags byte, the empty value encodes to only one byte
126//! assert_eq!(buffer.len(), 1 + 1 + 1 + 2 * 32);
127//!
128//! // Then actually encode the values
129//! enc_state.encode(&empty, &mut buffer).unwrap();
130//! enc_state.encode(&non_empty, &mut buffer).unwrap();
131//!
132//! // On the decoding end, create a state from byte buffer
133//! let mut dec_state = State::from_buffer(&buffer);
134//!
135//! // And decode directly to your own struct
136//! let empty_dec: MyStruct = dec_state.decode(&buffer).unwrap();
137//! let non_empty_dec: MyStruct = dec_state.decode(&buffer).unwrap();
138//! assert_eq!(empty_dec, empty);
139//! assert_eq!(non_empty_dec, non_empty);
140//! ```
141//!
142//! **NB**: This only works if you don't export your struct out of your crate.
143//! If you export the struct, orphan rule will require you to
144//! implement a wrapper for [State], e.g. `struct MyState(State);` and implement
145//! [CompactEncoding] for the wrapper struct instead.
146pub mod generic;
147pub mod types;
148pub use types::{CompactEncoding, EncodingError, EncodingErrorKind, State};