1use std::iter::once;
2
3use crate::{
4 Context, Error,
5 r#as::{ParseFully, Ref, Same},
6 bits::{
7 bitvec::{order::Msb0, slice::BitSlice, vec::BitVec},
8 de::BitReaderExt,
9 ser::BitWriterExt,
10 },
11 de::{CellDeserialize, CellDeserializeAs, CellParser, CellParserError},
12 ser::{CellBuilder, CellBuilderError, CellSerialize, CellSerializeAs},
13};
14use impl_tools::autoimpl;
15
16use super::hm_label::HmLabel;
17
18#[derive(Debug, Clone)]
27#[autoimpl(Deref using self.m)]
28#[autoimpl(DerefMut using self.m)]
29#[autoimpl(Default where E: Default)]
30pub struct HashmapAugE<T, E = ()> {
31 pub m: HashmapE<T, E>,
32 pub extra: E,
33}
34
35impl<T, AsT, E, AsE> CellSerializeAs<HashmapAugE<T, E>> for HashmapAugE<AsT, AsE>
36where
37 AsT: CellSerializeAs<T>,
38 AsT::Args: Clone,
39 AsE: CellSerializeAs<E>,
40 AsE::Args: Clone,
41{
42 type Args = (u32, AsT::Args, AsE::Args);
44
45 #[inline]
46 fn store_as(
47 source: &HashmapAugE<T, E>,
48 builder: &mut CellBuilder,
49 (n, node_args, extra_args): Self::Args,
50 ) -> Result<(), CellBuilderError> {
51 builder
52 .store_as::<_, &HashmapE<AsT, AsE>>(&source.m, (n, node_args, extra_args.clone()))?
53 .store_as::<_, &AsE>(&source.extra, extra_args)
55 .context("extra")?;
56 Ok(())
57 }
58}
59
60impl<'de, T, AsT, E, AsE> CellDeserializeAs<'de, HashmapAugE<T, E>> for HashmapAugE<AsT, AsE>
61where
62 AsT: CellDeserializeAs<'de, T>,
63 AsT::Args: Clone,
64 AsE: CellDeserializeAs<'de, E>,
65 AsE::Args: Clone,
66{
67 type Args = (u32, AsT::Args, AsE::Args);
69
70 #[inline]
71 fn parse_as(
72 parser: &mut CellParser<'de>,
73 (n, node_args, extra_args): Self::Args,
74 ) -> Result<HashmapAugE<T, E>, CellParserError<'de>> {
75 Ok(HashmapAugE {
76 m: parser.parse_as::<_, HashmapE<AsT, AsE>>((n, node_args, extra_args.clone()))?,
77 extra: parser.parse_as::<_, AsE>(extra_args).context("extra")?,
79 })
80 }
81}
82
83#[derive(Debug, Clone, PartialEq, Eq)]
91pub enum HashmapE<T, E = ()> {
92 Empty,
93 Root(Hashmap<T, E>),
94}
95
96impl<T, E> Default for HashmapE<T, E> {
97 #[inline]
98 fn default() -> Self {
99 Self::Empty
100 }
101}
102
103impl<T, E> HashmapE<T, E> {
104 #[inline]
106 pub const fn new() -> Self {
107 Self::Empty
108 }
109
110 #[inline]
112 pub const fn is_empty(&self) -> bool {
113 matches!(self, Self::Empty)
114 }
115
116 #[inline]
118 pub fn len(&self) -> usize {
119 match self {
120 Self::Empty => 0,
121 Self::Root(root) => root.len(),
122 }
123 }
124
125 #[inline]
127 pub fn contains_key(&self, key: impl AsRef<BitSlice<u8, Msb0>>) -> bool {
128 match self {
129 Self::Empty => false,
130 Self::Root(root) => root.contains_key(key),
131 }
132 }
133
134 #[inline]
136 pub fn get(&self, key: impl AsRef<BitSlice<u8, Msb0>>) -> Option<&T> {
137 match self {
138 Self::Empty => None,
139 Self::Root(root) => root.get(key),
140 }
141 }
142
143 #[inline]
145 pub fn get_mut(&mut self, key: impl AsRef<BitSlice<u8, Msb0>>) -> Option<&mut T> {
146 match self {
147 Self::Empty => None,
148 Self::Root(root) => root.get_mut(key),
149 }
150 }
151}
152
153impl<T, AsT, E, AsE> CellSerializeAs<HashmapE<T, E>> for HashmapE<AsT, AsE>
154where
155 AsT: CellSerializeAs<T>,
156 AsT::Args: Clone,
157 AsE: CellSerializeAs<E>,
158 AsE::Args: Clone,
159{
160 type Args = (u32, AsT::Args, AsE::Args);
162
163 #[inline]
164 fn store_as(
165 source: &HashmapE<T, E>,
166 builder: &mut CellBuilder,
167 args: Self::Args,
168 ) -> Result<(), CellBuilderError> {
169 match source {
170 HashmapE::Empty => builder
171 .pack(false, ())?,
173 HashmapE::Root(root) => builder
174 .pack(true, ())?
176 .store_as::<_, Ref<&Hashmap<AsT, AsE>>>(root, args)?,
178 };
179 Ok(())
180 }
181}
182
183impl<T, E> CellSerialize for HashmapE<T, E>
184where
185 T: CellSerialize,
186 T::Args: Clone,
187 E: CellSerialize,
188 E::Args: Clone,
189{
190 type Args = (u32, T::Args, E::Args);
192
193 #[inline]
194 fn store(&self, builder: &mut CellBuilder, args: Self::Args) -> Result<(), CellBuilderError> {
195 builder.store_as::<_, Same>(self, args)?;
196 Ok(())
197 }
198}
199
200impl<'de, T, AsT, E, AsE> CellDeserializeAs<'de, HashmapE<T, E>> for HashmapE<AsT, AsE>
201where
202 AsT: CellDeserializeAs<'de, T>,
203 AsT::Args: Clone,
204 AsE: CellDeserializeAs<'de, E>,
205 AsE::Args: Clone,
206{
207 type Args = (u32, AsT::Args, AsE::Args);
209
210 #[inline]
211 fn parse_as(
212 parser: &mut CellParser<'de>,
213 (n, node_args, extra_args): Self::Args,
214 ) -> Result<HashmapE<T, E>, CellParserError<'de>> {
215 Ok(match parser.unpack(())? {
216 false => HashmapE::Empty,
218 true => parser
220 .parse_as::<_, Ref<ParseFully<Hashmap<AsT, AsE>>>>((n, node_args, extra_args))
222 .map(HashmapE::Root)?,
223 })
224 }
225}
226
227impl<'de, T> CellDeserialize<'de> for HashmapE<T>
228where
229 T: CellDeserialize<'de>,
230 T::Args: Clone,
231{
232 type Args = (u32, T::Args);
234
235 #[inline]
236 fn parse(parser: &mut CellParser<'de>, args: Self::Args) -> Result<Self, CellParserError<'de>> {
237 parser.parse_as::<_, Same>(args)
238 }
239}
240
241impl<'de, T, As, C> CellDeserializeAs<'de, C> for HashmapE<As>
242where
243 C: IntoIterator<Item = (Key, T)> + Extend<(Key, T)> + Default, As: CellDeserializeAs<'de, T>,
245 As::Args: Clone,
246{
247 type Args = (u32, As::Args);
249
250 #[inline]
251 fn parse_as(
252 parser: &mut CellParser<'de>,
253 (n, node_args): Self::Args,
254 ) -> Result<C, CellParserError<'de>> {
255 Ok(match parser.unpack(())? {
256 false => C::default(),
258 true => parser
260 .parse_as::<_, Ref<ParseFully<Hashmap<As, ()>>>>((n, node_args))?,
262 })
263 }
264}
265
266#[derive(Debug, Clone, PartialEq, Eq)]
274pub struct Hashmap<T, E = ()> {
275 pub(super) prefix: BitVec<u8, Msb0>,
276 pub(super) node: HashmapAugNode<T, E>,
277}
278
279impl<T, E> Hashmap<T, E> {
280 #[inline]
281 pub fn new(prefix: impl Into<BitVec<u8, Msb0>>, node: HashmapAugNode<T, E>) -> Self {
282 Self {
283 prefix: prefix.into(),
284 node,
285 }
286 }
287
288 #[inline]
289 pub fn prefix(&self) -> &BitSlice<u8, Msb0> {
290 &self.prefix
291 }
292
293 #[inline]
294 #[allow(clippy::len_without_is_empty)]
295 pub fn len(&self) -> usize {
296 self.node.len()
297 }
298
299 #[inline]
300 pub fn contains_key(&self, key: impl AsRef<BitSlice<u8, Msb0>>) -> bool {
301 key.as_ref()
302 .strip_prefix(&self.prefix)
303 .is_some_and(|key| self.node.contains_key(key))
304 }
305
306 #[inline]
307 pub fn get(&self, key: impl AsRef<BitSlice<u8, Msb0>>) -> Option<&T> {
308 self.node.get(key.as_ref().strip_prefix(&self.prefix)?)
309 }
310
311 #[inline]
312 pub fn get_mut(&mut self, key: impl AsRef<BitSlice<u8, Msb0>>) -> Option<&mut T> {
313 self.node.get_mut(key.as_ref().strip_prefix(&self.prefix)?)
314 }
315}
316
317impl<T, AsT, E, AsE> CellSerializeAs<Hashmap<T, E>> for Hashmap<AsT, AsE>
318where
319 AsT: CellSerializeAs<T>,
320 AsT::Args: Clone,
321 AsE: CellSerializeAs<E>,
322 AsE::Args: Clone,
323{
324 type Args = (u32, AsT::Args, AsE::Args);
326
327 fn store_as(
328 source: &Hashmap<T, E>,
329 builder: &mut CellBuilder,
330 (n, node_args, extra_args): Self::Args,
331 ) -> Result<(), CellBuilderError> {
332 builder
333 .pack_as::<_, &HmLabel>(source.prefix.as_bitslice(), n)
335 .context("label")?
336 .store_as::<_, &HashmapAugNode<AsT, AsE>>(
338 &source.node,
339 (
340 n - source.prefix.len() as u32,
342 node_args,
343 extra_args,
344 ),
345 )
346 .context("node")?;
347 Ok(())
348 }
349}
350
351impl<'de, T, AsT, E, AsE> CellDeserializeAs<'de, Hashmap<T, E>> for Hashmap<AsT, AsE>
352where
353 AsT: CellDeserializeAs<'de, T>,
354 AsT::Args: Clone,
355 AsE: CellDeserializeAs<'de, E>,
356 AsE::Args: Clone,
357{
358 type Args = (u32, AsT::Args, AsE::Args);
360
361 #[inline]
362 fn parse_as(
363 parser: &mut CellParser<'de>,
364 (n, node_args, extra_args): Self::Args,
365 ) -> Result<Hashmap<T, E>, CellParserError<'de>> {
366 let prefix: BitVec<u8, Msb0> = parser.unpack_as::<_, HmLabel>(n).context("label")?;
368 let m = n - prefix.len() as u32;
370 Ok(Hashmap {
371 prefix,
372 node: parser
374 .parse_as::<_, HashmapAugNode<AsT, AsE>>((m, node_args, extra_args))
375 .context("node")?,
376 })
377 }
378}
379
380pub type Key = BitVec<u8, Msb0>;
381impl<'de, T, As, C> CellDeserializeAs<'de, C> for Hashmap<As>
382where
383 C: IntoIterator<Item = (Key, T)> + Extend<(Key, T)> + Default, As: CellDeserializeAs<'de, T>,
385 As::Args: Clone,
386{
387 type Args = (u32, As::Args);
389
390 #[inline]
391 fn parse_as(
392 parser: &mut CellParser<'de>,
393 (n, args): Self::Args,
394 ) -> Result<C, CellParserError<'de>> {
395 let mut output = C::default();
396 let mut stack: Vec<(u32, Key, CellParser<'de>)> = Vec::new();
397
398 #[inline]
399 fn parse<'de, T, As, C>(
400 parser: &mut CellParser<'de>,
401 stack: &mut Vec<(u32, Key, CellParser<'de>)>,
402 output: &mut C,
403 n: u32,
404 mut prefix: Key,
405 args: As::Args,
406 ) -> Result<(), CellParserError<'de>>
407 where
408 C: Extend<(Key, T)>,
409 As: CellDeserializeAs<'de, T>,
410 {
411 let next_prefix: BitVec<u8, Msb0> =
413 parser.unpack_as::<_, HmLabel>(n).context("label")?;
414 let m = n - next_prefix.len() as u32;
416
417 prefix.extend_from_bitslice(&next_prefix);
418
419 match m {
420 0 => output.extend(once((prefix, parser.parse_as::<_, As>(args)?))),
422 1.. => stack.extend(
424 parser
425 .parse_as::<_, [Ref; 2]>(())?
426 .into_iter()
427 .enumerate()
428 .map(|(next_prefix, parser)| {
430 let mut prefix = prefix.clone();
431 prefix.push(next_prefix != 0);
432
433 (m - 1, prefix, parser)
434 })
435 .rev(),
437 ),
438 }
439 Ok(())
440 }
441
442 parse::<_, As, C>(
443 parser,
444 &mut stack,
445 &mut output,
446 n,
447 Key::default(),
448 args.clone(),
449 )?;
450
451 while let Some((n, prefix, mut parser)) = stack.pop() {
452 parse::<_, As, C>(
453 &mut parser,
454 &mut stack,
455 &mut output,
456 n,
457 prefix,
458 args.clone(),
459 )?;
460 }
461
462 Ok(output)
463 }
464}
465
466#[derive(Debug, Clone, PartialEq, Eq)]
476pub enum HashmapNode<T, E = ()> {
477 Leaf(T),
478 Fork([Box<Hashmap<T, E>>; 2]),
480}
481
482impl<T, E> HashmapNode<T, E> {
483 #[inline]
484 #[allow(clippy::len_without_is_empty)]
485 pub fn len(&self) -> usize {
486 match self {
487 Self::Leaf(_) => 1,
488 Self::Fork([l, r]) => l.len() + r.len(),
489 }
490 }
491
492 #[inline]
493 pub fn contains_key(&self, key: impl AsRef<BitSlice<u8, Msb0>>) -> bool {
494 let key = key.as_ref();
495 match self {
496 Self::Leaf(_) if key.is_empty() => true,
497 Self::Fork([left, right]) => {
498 let Some((is_right, key)) = key.split_first() else {
499 return false;
500 };
501 if *is_right { right } else { left }.contains_key(key)
502 }
503 _ => false,
504 }
505 }
506
507 #[inline]
508 pub fn get(&self, key: impl AsRef<BitSlice<u8, Msb0>>) -> Option<&T> {
509 let key = key.as_ref();
510 match self {
511 Self::Leaf(v) if key.is_empty() => Some(v),
512 Self::Fork([left, right]) => {
513 let (is_right, key) = key.split_first()?;
514 if *is_right { right } else { left }.get(key)
515 }
516 _ => None,
517 }
518 }
519
520 #[inline]
521 pub fn get_mut(&mut self, key: impl AsRef<BitSlice<u8, Msb0>>) -> Option<&mut T> {
522 let key = key.as_ref();
523 match self {
524 Self::Leaf(v) if key.is_empty() => Some(v),
525 Self::Fork([left, right]) => {
526 let (is_right, key) = key.split_first()?;
527 if *is_right { right } else { left }.get_mut(key)
528 }
529 _ => None,
530 }
531 }
532}
533
534impl<T, AsT, E, AsE> CellSerializeAs<HashmapNode<T, E>> for HashmapNode<AsT, AsE>
535where
536 AsT: CellSerializeAs<T>,
537 AsT::Args: Clone,
538 AsE: CellSerializeAs<E>,
539 AsE::Args: Clone,
540{
541 type Args = (u32, AsT::Args, AsE::Args);
543
544 fn store_as(
545 source: &HashmapNode<T, E>,
546 builder: &mut CellBuilder,
547 (n, node_args, extra_args): Self::Args,
548 ) -> Result<(), CellBuilderError> {
549 match source {
550 HashmapNode::Leaf(value) => {
551 if n != 0 {
552 return Err(CellBuilderError::custom(format!(
553 "key is too small, {n} more bits required"
554 )));
555 }
556 builder.store_as::<_, &AsT>(value, node_args)?
558 }
559 HashmapNode::Fork(fork) => {
560 if n == 0 {
561 return Err(CellBuilderError::custom("key is too long"));
562 }
563 builder.store_as::<_, &[Box<Ref<Hashmap<AsT, AsE>>>; 2]>(
566 fork,
567 (n - 1, node_args, extra_args),
568 )?
569 }
570 };
571 Ok(())
572 }
573}
574
575impl<'de, T, AsT, E, AsE> CellDeserializeAs<'de, HashmapNode<T, E>> for HashmapNode<AsT, AsE>
576where
577 AsT: CellDeserializeAs<'de, T>,
578 AsT::Args: Clone,
579 AsE: CellDeserializeAs<'de, E>,
580 AsE::Args: Clone,
581{
582 type Args = (u32, AsT::Args, AsE::Args);
584
585 #[inline]
586 fn parse_as(
587 parser: &mut CellParser<'de>,
588 (n, node_args, extra_args): Self::Args,
589 ) -> Result<HashmapNode<T, E>, CellParserError<'de>> {
590 if n == 0 {
591 return parser.parse_as::<_, AsT>(node_args).map(HashmapNode::Leaf);
593 }
594
595 Ok(HashmapNode::Fork(
596 parser
597 .parse_as::<_, [Box<Ref<ParseFully<Hashmap<AsT, AsE>>>>; 2]>((
599 n - 1,
600 node_args,
601 extra_args,
602 ))?,
603 ))
604 }
605}
606
607#[derive(Debug, Clone, PartialEq, Eq)]
616#[autoimpl(Deref using self.node)]
617#[autoimpl(DerefMut using self.node)]
618pub struct HashmapAugNode<T, E = ()> {
619 pub node: HashmapNode<T, E>,
620 pub extra: E,
621}
622
623impl<T, E> HashmapAugNode<T, E> {
624 #[inline]
625 pub const fn new(node: HashmapNode<T, E>, extra: E) -> Self {
626 Self { node, extra }
627 }
628}
629
630impl<T, AsT, E, AsE> CellSerializeAs<HashmapAugNode<T, E>> for HashmapAugNode<AsT, AsE>
631where
632 AsT: CellSerializeAs<T>,
633 AsT::Args: Clone,
634 AsE: CellSerializeAs<E>,
635 AsE::Args: Clone,
636{
637 type Args = (u32, AsT::Args, AsE::Args);
639
640 fn store_as(
641 source: &HashmapAugNode<T, E>,
642 builder: &mut CellBuilder,
643 (n, node_args, extra_args): Self::Args,
644 ) -> Result<(), CellBuilderError> {
645 builder
646 .store_as::<_, &AsE>(&source.extra, extra_args.clone())?
648 .store_as::<_, &HashmapNode<AsT, AsE>>(&source.node, (n, node_args, extra_args))?;
649 Ok(())
650 }
651}
652
653impl<'de, T, AsT, E, AsE> CellDeserializeAs<'de, HashmapAugNode<T, E>> for HashmapAugNode<AsT, AsE>
654where
655 AsT: CellDeserializeAs<'de, T>,
656 AsT::Args: Clone,
657 AsE: CellDeserializeAs<'de, E>,
658 AsE::Args: Clone,
659{
660 type Args = (u32, AsT::Args, AsE::Args);
662
663 fn parse_as(
664 parser: &mut CellParser<'de>,
665 (n, node_args, extra_args): Self::Args,
666 ) -> Result<HashmapAugNode<T, E>, CellParserError<'de>> {
667 Ok(HashmapAugNode {
668 extra: parser.parse_as::<_, AsE>(extra_args.clone())?,
670 node: parser.parse_as::<_, HashmapNode<AsT, AsE>>((n, node_args, extra_args))?,
671 })
672 }
673}
674
675#[cfg(test)]
676mod tests {
677 use crate::{
678 Cell, Data,
679 bits::bitvec::{bits, order::Msb0, view::AsBits},
680 ser::{CellSerializeExt, CellSerializeWrapAsExt},
681 };
682 use std::collections::{BTreeMap, HashMap};
683
684 use super::*;
685
686 #[test]
687 fn parse() {
688 let cell = given_cell_from_example();
689
690 let hm: HashmapE<u16> = cell
691 .parse_fully_as::<_, HashmapE<Data, Same>>((8, (), ()))
692 .unwrap();
693
694 assert_eq!(hm.len(), 3);
695 assert_eq!(hm.get(1u8.to_be_bytes().as_bits()), Some(&777));
697 assert_eq!(hm.get(17u8.to_be_bytes().as_bits()), Some(&111));
699 assert_eq!(hm.get(128u8.to_be_bytes().as_bits()), Some(&777));
701
702 let mut builder = Cell::builder();
703 builder
704 .store_as::<_, HashmapE<Data, Same>>(hm, (8, (), ()))
705 .unwrap();
706 let got = builder.into_cell();
707 assert_eq!(got, cell);
708 }
709
710 #[test]
711 fn hashmape_parse_as_std_hashmap() {
712 let cell = given_cell_from_example();
713
714 let hm: HashMap<Key, u16> = cell.parse_fully_as::<_, HashmapE<Data>>((8, ())).unwrap();
715
716 assert_eq!(hm.len(), 3);
717 assert_eq!(hm.get(1u8.to_be_bytes().as_bits()), Some(&777));
719 assert_eq!(hm.get(17u8.to_be_bytes().as_bits()), Some(&111));
721 assert_eq!(hm.get(128u8.to_be_bytes().as_bits()), Some(&777));
723 }
724
725 #[test]
726 fn hashmape_parse_as_std_btreemap() {
727 let cell = given_cell_from_example();
728
729 let hm: BTreeMap<Key, u16> = cell.parse_fully_as::<_, HashmapE<Data>>((8, ())).unwrap();
730
731 assert_eq!(hm.len(), 3);
732 assert_eq!(hm.get(1u8.to_be_bytes().as_bits()), Some(&777));
734 assert_eq!(hm.get(17u8.to_be_bytes().as_bits()), Some(&111));
736 assert_eq!(hm.get(128u8.to_be_bytes().as_bits()), Some(&777));
738 }
739
740 fn given_cell_from_example() -> Cell {
742 (
743 bits![u8, Msb0; 1].wrap_as::<Data>(),
744 (
745 bits![u8, Msb0; 0,0].wrap_as::<Data>(),
746 (
747 bits![u8, Msb0; 0,1,1,0,0,0].wrap_as::<Data>(),
750 bits![u8, Msb0; 1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1]
751 .wrap_as::<Ref<Data>>(),
752 bits![u8, Msb0; 1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1]
753 .wrap_as::<Ref<Data>>(),
754 )
755 .wrap_as::<Ref>(),
756 bits![u8, Msb0; 1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1].wrap_as::<Ref<Data>>(),
759 )
760 .wrap_as::<Ref>(),
761 )
762 .to_cell(((), ((), ((), (), ()), ())))
763 .unwrap()
764 }
765}