1use core::{iter, mem};
2use std::{borrow::Cow, sync::Arc};
3
4use tlbits::Context;
5
6use crate::{
7 Cell, Error,
8 bits::{
9 bitvec::{order::Msb0, slice::BitSlice},
10 de::BitReader,
11 },
12};
13
14use super::{CellDeserialize, CellDeserializeAs};
15
16pub type CellParserError<'de> = <CellParser<'de> as BitReader<'de>>::Error;
18
19#[derive(Clone)]
21pub struct CellParser<'de> {
22 pub(super) is_exotic: bool,
23 pub(super) data: &'de BitSlice<u8, Msb0>,
24 pub(super) references: &'de [Arc<Cell>],
25}
26
27impl<'de> CellParser<'de> {
28 #[inline]
29 pub(crate) const fn new(
30 is_exotic: bool,
31 data: &'de BitSlice<u8, Msb0>,
32 references: &'de [Arc<Cell>],
33 ) -> Self {
34 Self {
35 is_exotic,
36 data,
37 references,
38 }
39 }
40
41 #[inline]
44 pub fn parse<T>(&mut self, args: T::Args) -> Result<T, CellParserError<'de>>
45 where
46 T: CellDeserialize<'de>,
47 {
48 T::parse(self, args)
49 }
50
51 #[inline]
54 pub fn parse_iter<'a: 'de, T>(
55 &mut self,
56 args: T::Args,
57 ) -> impl Iterator<Item = Result<T, CellParserError<'de>>> + '_
58 where
59 T: CellDeserialize<'de>,
60 T::Args: Clone + 'a,
61 {
62 iter::repeat_with(move || self.parse(args.clone()))
63 .enumerate()
64 .map(|(i, v)| v.with_context(|| format!("[{i}]")))
65 }
66
67 #[inline]
73 pub fn parse_as<T, As>(&mut self, args: As::Args) -> Result<T, CellParserError<'de>>
74 where
75 As: CellDeserializeAs<'de, T> + ?Sized,
76 {
77 As::parse_as(self, args)
78 }
79
80 #[inline]
86 pub fn parse_iter_as<'a: 'de, T, As>(
87 &mut self,
88 args: As::Args,
89 ) -> impl Iterator<Item = Result<T, CellParserError<'de>>> + '_
90 where
91 As: CellDeserializeAs<'de, T> + ?Sized,
92 As::Args: Clone + 'a,
93 {
94 iter::repeat_with(move || self.parse_as::<_, As>(args.clone()))
95 .enumerate()
96 .map(|(i, v)| v.with_context(|| format!("[{i}]")))
97 }
98
99 #[inline]
100 fn pop_reference(&mut self) -> Result<&'de Arc<Cell>, CellParserError<'de>> {
101 let (first, rest) = self
102 .references
103 .split_first()
104 .ok_or_else(|| Error::custom("no more references left"))?;
105 self.references = rest;
106 Ok(first)
107 }
108
109 #[inline]
110 pub(crate) fn parse_reference_as<T, As>(
111 &mut self,
112 args: As::Args,
113 ) -> Result<T, CellParserError<'de>>
114 where
115 As: CellDeserializeAs<'de, T> + ?Sized,
116 {
117 self.pop_reference()?.parse_fully_as::<T, As>(args)
118 }
119
120 #[inline]
121 pub fn bits_left(&self) -> usize {
122 self.data.len()
123 }
124
125 #[inline]
126 pub fn no_bits_left(&self) -> bool {
127 self.bits_left() == 0
128 }
129
130 #[inline]
131 pub const fn references_left(&self) -> usize {
132 self.references.len()
133 }
134
135 #[inline]
136 pub const fn no_references_left(&self) -> bool {
137 self.references_left() == 0
138 }
139
140 #[inline]
142 pub fn is_empty(&self) -> bool {
143 self.no_bits_left() && self.no_references_left()
144 }
145
146 #[inline]
148 pub fn ensure_empty(&self) -> Result<(), CellParserError<'de>> {
149 if !self.is_empty() {
150 return Err(Error::custom(format!(
151 "more data left: {} bits, {} references",
152 self.data.len(),
153 self.references.len(),
154 )));
155 }
156 Ok(())
157 }
158
159 #[inline]
161 pub const fn is_exotic(&self) -> bool {
162 self.is_exotic
163 }
164
165 #[inline]
167 pub fn ensure_exotic(&self) -> Result<(), CellParserError<'de>> {
168 if !self.is_exotic() {
169 return Err(Error::custom("cell is not exotic"));
170 }
171 Ok(())
172 }
173
174 #[inline]
176 pub fn ensure_ordinary(&self) -> Result<(), CellParserError<'de>> {
177 if self.is_exotic() {
178 return Err(Error::custom("cell is not ordinary"));
179 }
180 Ok(())
181 }
182}
183
184impl<'de> BitReader<'de> for CellParser<'de> {
185 type Error = <&'de BitSlice<u8, Msb0> as BitReader<'de>>::Error;
186
187 #[inline]
188 fn bits_left(&self) -> usize {
189 self.data.len()
190 }
191
192 #[inline]
193 fn read_bit(&mut self) -> Result<Option<bool>, Self::Error> {
194 self.data.read_bit()
195 }
196
197 #[inline]
198 fn read_bits_into(&mut self, dst: &mut BitSlice<u8, Msb0>) -> Result<usize, Self::Error> {
199 self.data.read_bits_into(dst)
200 }
201
202 #[inline]
203 fn read_bits(&mut self, n: usize) -> Result<Cow<'de, BitSlice<u8, Msb0>>, Self::Error> {
204 self.data.read_bits(n)
205 }
206
207 #[inline]
208 fn skip(&mut self, n: usize) -> Result<usize, Self::Error> {
209 self.data.skip(n)
210 }
211}
212
213impl<'de> CellDeserialize<'de> for CellParser<'de> {
214 type Args = ();
215
216 #[inline]
217 fn parse(parser: &mut Self, (): Self::Args) -> Result<Self, CellParserError<'de>> {
218 Ok(Self {
219 is_exotic: parser.is_exotic,
220 data: mem::take(&mut parser.data),
221 references: mem::take(&mut parser.references),
222 })
223 }
224}