Skip to main content

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;