tlbits/lib.rs
1#![doc = include_str!("../README.md")]
2//! ## Example
3//!
4//! Consider the following TL-B schema:
5//!
6//! ```tlb
7//! tag$10 query_id:uint64 amount:(VarUInteger 16) = Hello;
8//! ```
9//!
10//! Let's first define a struct `Hello` that holds these parameters:
11//!
12//! ```rust
13//! # use num_bigint::BigUint;
14//! struct Hello {
15//! pub query_id: u64,
16//! pub amount: BigUint,
17//! }
18//! ```
19//!
20//! ### **Ser**ialization
21//!
22//! To be able to **ser**ialize a type to [`BitWriter`](crate::ser::BitWriter),
23//! we should implement [`BitPack`](crate::ser::BitPack) on it:
24//!
25//! ```
26//! # use bitvec::{vec::BitVec, order::Msb0};
27//! # use num_bigint::BigUint;
28//! # use tlbits::{
29//! # r#as::{NBits, VarInt},
30//! # ser::{BitPack, BitWriter, BitWriterExt, pack},
31//! # StringError,
32//! # };
33//! #
34//! # struct Hello {
35//! # pub query_id: u64,
36//! # pub amount: BigUint,
37//! # }
38//! impl BitPack for Hello {
39//! fn pack<W>(&self, mut writer: W) -> Result<(), W::Error>
40//! where W: BitWriter,
41//! {
42//! writer
43//! // tag$10
44//! .pack_as::<_, NBits<2>>(0b10)?
45//! // query_id:uint64
46//! .pack(self.query_id)?
47//! // amount:(VarUInteger 16)
48//! .pack_as::<_, &VarInt<4>>(&self.amount)?;
49//! Ok(())
50//! }
51//! }
52//!
53//! # fn main() -> Result<(), StringError> {
54//! # let mut writer = BitVec::<u8, Msb0>::new().counted();
55//! writer.pack(Hello {
56//! query_id: 0,
57//! amount: 1_000u64.into(),
58//! })?;
59//! # Ok(())
60//! # }
61//! ```
62//!
63//! ### **De**serialization
64//!
65//! To be able to **de**serialize a type from [`BitReader`](crate::de::BitReader),
66//! we should implement [`BitUnpack`](crate::de::BitUnpack) on it:
67//!
68//! ```rust
69//! # use bitvec::{vec::BitVec, order::Msb0};
70//! # use num_bigint::BigUint;
71//! # use tlbits::{
72//! # r#as::{NBits, VarInt},
73//! # de::{BitReaderExt, BitReader, BitUnpack},
74//! # Error,
75//! # ser::{BitPack, BitWriter, BitWriterExt, pack},
76//! # StringError,
77//! # };
78//! # #[derive(Debug, PartialEq)]
79//! # struct Hello {
80//! # pub query_id: u64,
81//! # pub amount: BigUint,
82//! # }
83//! # impl BitPack for Hello {
84//! # fn pack<W>(&self, mut writer: W) -> Result<(), W::Error>
85//! # where W: BitWriter,
86//! # {
87//! # writer
88//! # // tag$10
89//! # .pack_as::<_, NBits<2>>(0b10)?
90//! # // query_id:uint64
91//! # .pack(self.query_id)?
92//! # // amount:(VarUInteger 16)
93//! # .pack_as::<_, &VarInt<4>>(&self.amount)?;
94//! # Ok(())
95//! # }
96//! # }
97//! impl BitUnpack for Hello {
98//! fn unpack<R>(mut reader: R) -> Result<Self, R::Error>
99//! where R: BitReader,
100//! {
101//! // tag$10
102//! let tag: u8 = reader.unpack_as::<_, NBits<2>>()?;
103//! if tag != 0b10 {
104//! return Err(Error::custom(format!("unknown tag: {tag:#b}")));
105//! }
106//! Ok(Self {
107//! // query_id:uint64
108//! query_id: reader.unpack()?,
109//! // amount:(VarUInteger 16)
110//! amount: reader.unpack_as::<_, VarInt<4>>()?,
111//! })
112//! }
113//! }
114//!
115//! # fn main() -> Result<(), StringError> {
116//! # let orig = Hello {
117//! # query_id: 0,
118//! # amount: 1_000u64.into(),
119//! # };
120//! # let mut writer = BitVec::<u8, Msb0>::new().counted();
121//! # writer.pack(&orig)?;
122//! # let mut parser = writer.as_bitslice();
123//! let hello: Hello = parser.unpack()?;
124//! # assert_eq!(hello, orig);
125//! # Ok(())
126//! # }
127//! ```
128pub mod adapters;
129pub mod r#as;
130pub mod de;
131mod error;
132pub mod integer;
133pub mod ser;
134
135pub use self::error::*;
136
137pub use bitvec;
138pub use either;
139
140#[cfg(test)]
141mod tests;