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;