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//! # 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//! type Args = ();
40//!
41//! fn pack<W>(&self, writer: &mut W, _: Self::Args) -> Result<(), W::Error>
42//! where W: BitWriter + ?Sized,
43//! {
44//! writer
45//! // tag$10
46//! .pack_as::<_, NBits<2>>(0b10, ())?
47//! // query_id:uint64
48//! .pack(self.query_id, ())?
49//! // amount:(VarUInteger 16)
50//! .pack_as::<_, &VarInt<4>>(&self.amount, ())?;
51//! Ok(())
52//! }
53//! }
54//!
55//! # fn main() -> Result<(), StringError> {
56//! # let mut writer = BitVec::<u8, Msb0>::new().counted();
57//! writer.pack(Hello {
58//! query_id: 0,
59//! amount: 1_000u64.into(),
60//! }, ())?;
61//! # Ok(())
62//! # }
63//! ```
64//!
65//! ### **De**serialization
66//!
67//! To be able to **de**serialize a type from [`BitReader`](crate::de::BitReader),
68//! we should implement [`BitUnpack`](crate::de::BitUnpack) on it:
69//!
70//! ```rust
71//! # use bitvec::{vec::BitVec, order::Msb0};
72//! # use num_bigint::BigUint;
73//! # use tlbits::{
74//! # NBits, VarInt,
75//! # de::{BitReaderExt, BitReader, BitUnpack},
76//! # Error,
77//! # ser::{BitPack, BitWriter, BitWriterExt, pack},
78//! # StringError,
79//! # };
80//! # #[derive(Debug, PartialEq)]
81//! # struct Hello {
82//! # pub query_id: u64,
83//! # pub amount: BigUint,
84//! # }
85//! # impl BitPack for Hello {
86//! # type Args = ();
87//! #
88//! # fn pack<W>(&self, writer: &mut W, _: Self::Args) -> Result<(), W::Error>
89//! # where W: BitWriter + ?Sized,
90//! # {
91//! # writer
92//! # // tag$10
93//! # .pack_as::<_, NBits<2>>(0b10, ())?
94//! # // query_id:uint64
95//! # .pack(self.query_id, ())?
96//! # // amount:(VarUInteger 16)
97//! # .pack_as::<_, &VarInt<4>>(&self.amount, ())?;
98//! # Ok(())
99//! # }
100//! # }
101//! impl<'de> BitUnpack<'de> for Hello {
102//! type Args = ();
103//!
104//! fn unpack<R>(reader: &mut R, _: Self::Args) -> Result<Self, R::Error>
105//! where R: BitReader<'de> + ?Sized,
106//! {
107//! // tag$10
108//! let tag: u8 = reader.unpack_as::<_, NBits<2>>(())?;
109//! if tag != 0b10 {
110//! return Err(Error::custom(format!("unknown tag: {tag:#b}")));
111//! }
112//! Ok(Self {
113//! // query_id:uint64
114//! query_id: reader.unpack(())?,
115//! // amount:(VarUInteger 16)
116//! amount: reader.unpack_as::<_, VarInt<4>>(())?,
117//! })
118//! }
119//! }
120//!
121//! # fn main() -> Result<(), StringError> {
122//! # let orig = Hello {
123//! # query_id: 0,
124//! # amount: 1_000u64.into(),
125//! # };
126//! # let mut writer = BitVec::<u8, Msb0>::new().counted();
127//! # writer.pack(&orig, ())?;
128//! # let mut parser = writer.as_bitslice();
129//! let hello: Hello = parser.unpack(())?;
130//! # assert_eq!(hello, orig);
131//! # Ok(())
132//! # }
133//! ```
134pub mod adapters;
135mod r#as;
136pub mod de;
137mod error;
138pub mod integer;
139pub mod ser;
140
141pub use self::{r#as::*, error::*};
142
143pub use bitvec;
144pub use either;
145
146#[cfg(test)]
147mod tests;