tlb/
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) payload:(Maybe ^Cell) = Hello;
8//! ```
9//!
10//! Let's first define a struct `Hello` that holds these parameters:
11//!
12//! ```rust
13//! # use num_bigint::BigUint;
14//! # use tlb::Cell;
15//! struct Hello {
16//!     pub query_id: u64,
17//!     pub amount: BigUint,
18//!     pub payload: Option<Cell>,
19//! }
20//! ```
21//!
22//! ### **Ser**ialization
23//!
24//! To be able to **ser**ialize a type to [`Cell`], we should implement
25//! [`CellSerialize`](crate::ser::CellSerialize) on it:
26//!
27//! ```
28//! # use num_bigint::BigUint;
29//! # use tlb::{
30//! #   r#as::Ref,
31//! #   bits::{r#as::{NBits, VarInt}, ser::BitWriterExt},
32//! #   Cell,
33//! #   ser::{CellSerialize, CellBuilder, CellBuilderError, CellSerializeExt},
34//! #   StringError,
35//! # };
36//! #
37//! # struct Hello {
38//! #     pub query_id: u64,
39//! #     pub amount: BigUint,
40//! #     pub payload: Option<Cell>,
41//! # }
42//! impl CellSerialize for Hello {
43//!     fn store(&self, builder: &mut CellBuilder) -> Result<(), CellBuilderError> {
44//!         builder
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//!             // payload:(Maybe ^Cell)
52//!             .store_as::<_, Option<Ref>>(self.payload.as_ref())?;
53//!         Ok(())
54//!     }
55//! }
56//!
57//! # fn main() -> Result<(), StringError> {
58//! // serialize value into cell
59//! let hello = Hello {
60//!     query_id: 0,
61//!     amount: 1_000u64.into(),
62//!     payload: None,
63//! };
64//! let cell = hello.to_cell()?;
65//! # Ok(())
66//! # }
67//! ```
68//!
69//! ### **De**serialization
70//!
71//! To be able to **de**serialize a type from [`Cell`], we should implement
72//! [`CellDeserialize`](crate::de::CellDeserialize) on it:
73//!
74//! ```rust
75//! # use num_bigint::BigUint;
76//! # use tlb::{
77//! #   r#as::{Ref, ParseFully},
78//! #   bits::{r#as::{NBits, VarInt}, de::BitReaderExt, ser::BitWriterExt},
79//! #   Cell,
80//! #   de::{CellDeserialize, CellParser, CellParserError},
81//! #   Error,
82//! #   ser::{CellSerialize, CellBuilder, CellBuilderError, CellSerializeExt},
83//! #   StringError,
84//! # };
85//! # #[derive(Debug, PartialEq)]
86//! # struct Hello {
87//! #     pub query_id: u64,
88//! #     pub amount: BigUint,
89//! #     pub payload: Option<Cell>,
90//! # }
91//! # impl CellSerialize for Hello {
92//! #     fn store(&self, builder: &mut CellBuilder) -> Result<(), CellBuilderError> {
93//! #         builder
94//! #             // tag$10
95//! #             .pack_as::<_, NBits<2>>(0b10)?
96//! #             // query_id:uint64
97//! #             .pack(self.query_id)?
98//! #             // amount:(VarUInteger 16)
99//! #             .pack_as::<_, &VarInt<4>>(&self.amount)?
100//! #             // payload:(Maybe ^Cell)
101//! #             .store_as::<_, Option<Ref>>(self.payload.as_ref())?;
102//! #         Ok(())
103//! #     }
104//! # }
105//! impl<'de> CellDeserialize<'de> for Hello {
106//!     fn parse(parser: &mut CellParser<'de>) -> Result<Self, CellParserError<'de>> {
107//!         // tag$10
108//!         let tag: u8 = parser.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: parser.unpack()?,
115//!             // amount:(VarUInteger 16)
116//!             amount: parser.unpack_as::<_, VarInt<4>>()?,
117//!             // payload:(Maybe ^Cell)
118//!             payload: parser.parse_as::<_, Option<Ref<ParseFully>>>()?,
119//!         })
120//!     }
121//! }
122//!
123//! # fn main() -> Result<(), StringError> {
124//! # let orig = Hello {
125//! #     query_id: 0,
126//! #     amount: 1_000u64.into(),
127//! #     payload: None,
128//! # };
129//! # let cell = orig.to_cell()?;
130//! let mut parser = cell.parser();
131//! let hello: Hello = parser.parse()?;
132//! # assert_eq!(hello, orig);
133//! # Ok(())
134//! # }
135//! ```
136pub mod r#as;
137mod boc;
138mod cell;
139pub mod de;
140pub mod ser;
141
142pub use self::{boc::*, cell::*};
143
144pub use tlbits::{self as bits, Context, Error, StringError, either};
145
146#[cfg(test)]
147mod tests;