Skip to main content

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;