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//! # Ref,
31//! # bits::{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//! type Args = ();
44//!
45//! fn store(&self, builder: &mut CellBuilder, _: Self::Args) -> Result<(), CellBuilderError> {
46//! builder
47//! // tag$10
48//! .pack_as::<_, NBits<2>>(0b10, ())?
49//! // query_id:uint64
50//! .pack(self.query_id, ())?
51//! // amount:(VarUInteger 16)
52//! .pack_as::<_, &VarInt<4>>(&self.amount, ())?
53//! // payload:(Maybe ^Cell)
54//! .store_as::<_, Option<Ref>>(self.payload.as_ref(), ())?;
55//! Ok(())
56//! }
57//! }
58//!
59//! # fn main() -> Result<(), StringError> {
60//! // serialize value into cell
61//! let hello = Hello {
62//! query_id: 0,
63//! amount: 1_000u64.into(),
64//! payload: None,
65//! };
66//! let cell = hello.to_cell(())?;
67//! # Ok(())
68//! # }
69//! ```
70//!
71//! ### **De**serialization
72//!
73//! To be able to **de**serialize a type from [`Cell`], we should implement
74//! [`CellDeserialize`](crate::de::CellDeserialize) on it:
75//!
76//! ```rust
77//! # use num_bigint::BigUint;
78//! # use tlb::{
79//! # Ref, ParseFully,
80//! # bits::{NBits, VarInt, de::BitReaderExt, ser::BitWriterExt},
81//! # Cell,
82//! # de::{CellDeserialize, CellParser, CellParserError},
83//! # Error,
84//! # ser::{CellSerialize, CellBuilder, CellBuilderError, CellSerializeExt},
85//! # StringError,
86//! # };
87//! # #[derive(Debug, PartialEq)]
88//! # struct Hello {
89//! # pub query_id: u64,
90//! # pub amount: BigUint,
91//! # pub payload: Option<Cell>,
92//! # }
93//! # impl CellSerialize for Hello {
94//! # type Args = ();
95//! #
96//! # fn store(&self, builder: &mut CellBuilder, _: Self::Args) -> Result<(), CellBuilderError> {
97//! # builder
98//! # // tag$10
99//! # .pack_as::<_, NBits<2>>(0b10, ())?
100//! # // query_id:uint64
101//! # .pack(self.query_id, ())?
102//! # // amount:(VarUInteger 16)
103//! # .pack_as::<_, &VarInt<4>>(&self.amount, ())?
104//! # // payload:(Maybe ^Cell)
105//! # .store_as::<_, Option<Ref>>(self.payload.as_ref(), ())?;
106//! # Ok(())
107//! # }
108//! # }
109//! impl<'de> CellDeserialize<'de> for Hello {
110//! type Args = ();
111//!
112//! fn parse(parser: &mut CellParser<'de>, _: Self::Args) -> Result<Self, CellParserError<'de>> {
113//! // tag$10
114//! let tag: u8 = parser.unpack_as::<_, NBits<2>>(())?;
115//! if tag != 0b10 {
116//! return Err(Error::custom(format!("unknown tag: {tag:#b}")));
117//! }
118//! Ok(Self {
119//! // query_id:uint64
120//! query_id: parser.unpack(())?,
121//! // amount:(VarUInteger 16)
122//! amount: parser.unpack_as::<_, VarInt<4>>(())?,
123//! // payload:(Maybe ^Cell)
124//! payload: parser.parse_as::<_, Option<Ref<ParseFully>>>(())?,
125//! })
126//! }
127//! }
128//!
129//! # fn main() -> Result<(), StringError> {
130//! # let orig = Hello {
131//! # query_id: 0,
132//! # amount: 1_000u64.into(),
133//! # payload: None,
134//! # };
135//! # let cell = orig.to_cell(())?;
136//! let mut parser = cell.parser();
137//! let hello: Hello = parser.parse(())?;
138//! # assert_eq!(hello, orig);
139//! # Ok(())
140//! # }
141//! ```
142mod r#as;
143mod boc;
144mod cell;
145pub mod de;
146pub mod ser;
147
148pub use self::{r#as::*, boc::*, cell::*};
149
150pub use tlbits::{self as bits, Context, Error, StringError, either};
151
152#[cfg(test)]
153mod tests;