1use impl_tools::autoimpl;
3use tlb::{
4 Cell, ParseFully, Ref, Same,
5 bits::{
6 NBits, NoArgs,
7 de::{BitReader, BitReaderExt, BitUnpack},
8 ser::{BitPack, BitWriter, BitWriterExt},
9 },
10 de::{CellDeserialize, CellParser, CellParserError},
11 hashmap::HashmapE,
12 ser::{CellBuilder, CellBuilderError, CellSerialize, CellSerializeExt},
13};
14
15#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
22#[derive(Debug, Clone, PartialEq, Eq)]
23#[autoimpl(Default)]
24pub struct StateInit<C = Cell, D = Cell> {
25 pub split_depth: Option<u8>,
26 pub special: Option<TickTock>,
27 pub code: Option<C>,
28 pub data: Option<D>,
29 #[cfg_attr(feature = "arbitrary", arbitrary(default))] pub library: HashmapE<SimpleLib>,
31}
32
33impl<IC, ID> StateInit<IC, ID>
34where
35 IC: CellSerialize<Args: NoArgs>,
36 ID: CellSerialize<Args: NoArgs>,
37{
38 #[inline]
39 pub fn normalize(&self) -> Result<StateInit, CellBuilderError> {
40 Ok(StateInit {
41 split_depth: self.split_depth,
42 special: self.special,
43 code: self
44 .code
45 .as_ref()
46 .map(|c| c.to_cell(NoArgs::EMPTY))
47 .transpose()?,
48 data: self
49 .data
50 .as_ref()
51 .map(|d| d.to_cell(NoArgs::EMPTY))
52 .transpose()?,
53 library: self.library.clone(),
54 })
55 }
56}
57
58impl<C, D> CellSerialize for StateInit<C, D>
59where
60 C: CellSerialize<Args: NoArgs>,
61 D: CellSerialize<Args: NoArgs>,
62{
63 type Args = ();
64
65 #[inline]
66 fn store(&self, builder: &mut CellBuilder, (): Self::Args) -> Result<(), CellBuilderError> {
67 builder
68 .pack_as::<_, Option<NBits<5>>>(self.split_depth, ())?
70 .pack(self.special, ())?
72 .store_as::<_, Option<Ref>>(self.code.as_ref(), NoArgs::EMPTY)?
74 .store_as::<_, Option<Ref>>(self.data.as_ref(), NoArgs::EMPTY)?
76 .store_as::<_, &HashmapE<Same, Same>>(&self.library, (256, (), ()))?;
78 Ok(())
79 }
80}
81
82impl<'de, C, D> CellDeserialize<'de> for StateInit<C, D>
83where
84 C: CellDeserialize<'de, Args: NoArgs>,
85 D: CellDeserialize<'de, Args: NoArgs>,
86{
87 type Args = ();
88
89 #[inline]
90 fn parse(parser: &mut CellParser<'de>, (): Self::Args) -> Result<Self, CellParserError<'de>> {
91 Ok(Self {
92 split_depth: parser.unpack_as::<_, Option<NBits<5>>>(())?,
94 special: parser.unpack(())?,
96 code: parser.parse_as::<_, Option<Ref<ParseFully>>>(NoArgs::EMPTY)?,
98 data: parser.parse_as::<_, Option<Ref<ParseFully>>>(NoArgs::EMPTY)?,
100 library: parser.parse_as::<_, HashmapE<Same, Same>>((256, (), ()))?,
102 })
103 }
104}
105
106#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub struct TickTock {
113 pub tick: bool,
114 pub tock: bool,
115}
116
117impl BitPack for TickTock {
118 type Args = ();
119
120 #[inline]
121 fn pack<W>(&self, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
122 where
123 W: BitWriter + ?Sized,
124 {
125 writer.pack(self.tick, ())?.pack(self.tock, ())?;
126 Ok(())
127 }
128}
129
130impl<'de> BitUnpack<'de> for TickTock {
131 type Args = ();
132
133 #[inline]
134 fn unpack<R>(reader: &mut R, (): Self::Args) -> Result<Self, R::Error>
135 where
136 R: BitReader<'de> + ?Sized,
137 {
138 Ok(Self {
139 tick: reader.unpack(())?,
140 tock: reader.unpack(())?,
141 })
142 }
143}
144
145#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
150#[derive(Debug, Clone, PartialEq, Eq)]
151pub struct SimpleLib {
152 pub public: bool,
153 pub root: Cell,
154}
155
156impl CellSerialize for SimpleLib {
157 type Args = ();
158
159 #[inline]
160 fn store(&self, builder: &mut CellBuilder, (): Self::Args) -> Result<(), CellBuilderError> {
161 builder
162 .pack(self.public, ())?
163 .store_as::<_, Ref>(&self.root, ())?;
164 Ok(())
165 }
166}
167
168impl<'de> CellDeserialize<'de> for SimpleLib {
169 type Args = ();
170
171 #[inline]
172 fn parse(parser: &mut CellParser<'de>, (): Self::Args) -> Result<Self, CellParserError<'de>> {
173 Ok(Self {
174 public: parser.unpack(())?,
175 root: parser.parse_as::<_, Ref>(())?,
176 })
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use tlb::ser::CellSerializeExt;
183
184 use super::*;
185
186 #[test]
187 fn state_init_serde() {
188 let s = StateInit::<(), ()>::default();
189 let cell = s.to_cell(()).unwrap();
190 let got: StateInit<(), ()> = cell.parse_fully(()).unwrap();
191 assert_eq!(got, s);
192 }
193}