tycho_types/dict/
raw.rs

1use std::collections::BTreeMap;
2
3use super::{
4    build_dict_from_sorted_iter, dict_find_bound, dict_find_bound_owned, dict_find_owned, dict_get,
5    dict_get_owned, dict_get_subdict, dict_insert, dict_load_from_root, dict_remove_bound_owned,
6    dict_remove_owned, dict_split_by_prefix, read_label, DictBound, DictOwnedEntry, SetMode,
7    StoreDictKey,
8};
9use crate::cell::*;
10use crate::error::Error;
11use crate::util::{unlikely, IterStatus};
12
13/// Dictionary with fixed length keys (where `N` is a number of bits in each key).
14///
15/// # TLB scheme
16///
17/// ```text
18/// // ordinary Hashmap / HashmapE, with fixed length keys
19///
20/// hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
21///           {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X;
22///
23/// hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
24/// hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X)
25///            right:^(Hashmap n X) = HashmapNode (n + 1) X;
26///
27/// hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= m} s:(n * Bit) = HmLabel ~n m;
28/// hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
29/// hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m;
30///
31/// hme_empty$0 {n:#} {X:Type} = HashmapE n X;
32/// hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X;
33///
34/// unary_zero$0 = Unary ~0;
35/// unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);
36///
37/// bit$_ (## 1) = Bit;
38/// ```
39pub struct RawDict<const N: u16>(pub(crate) Option<Cell>);
40
41impl<const N: u16> ExactSize for RawDict<N> {
42    #[inline]
43    fn exact_size(&self) -> Size {
44        Size {
45            bits: 1,
46            refs: self.0.is_some() as u8,
47        }
48    }
49}
50
51impl<'a, const N: u16> Load<'a> for RawDict<N> {
52    #[inline]
53    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
54        match <_>::load_from(slice) {
55            Ok(dict) => Ok(Self(dict)),
56            Err(e) => Err(e),
57        }
58    }
59}
60
61impl<const N: u16> Store for RawDict<N> {
62    #[inline]
63    fn store_into(
64        &self,
65        builder: &mut CellBuilder,
66        context: &dyn CellContext,
67    ) -> Result<(), Error> {
68        self.0.store_into(builder, context)
69    }
70}
71
72impl<const N: u16> Default for RawDict<N> {
73    #[inline]
74    fn default() -> Self {
75        Self(None)
76    }
77}
78
79impl<const N: u16> Clone for RawDict<N> {
80    fn clone(&self) -> Self {
81        Self(self.0.clone())
82    }
83}
84
85impl<const N: u16> Eq for RawDict<N> {}
86impl<const N: u16> PartialEq for RawDict<N> {
87    fn eq(&self, other: &Self) -> bool {
88        match (&self.0, &other.0) {
89            (Some(this), Some(other)) => this.as_ref() == other.as_ref(),
90            (None, None) => true,
91            _ => false,
92        }
93    }
94}
95
96impl<const N: u16> From<Option<Cell>> for RawDict<N> {
97    #[inline]
98    fn from(value: Option<Cell>) -> Self {
99        Self(value)
100    }
101}
102
103impl<const N: u16> std::fmt::Debug for RawDict<N> {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        f.debug_struct("RawDict")
106            .field("key_bit_len", &N)
107            .field("root", &self.0)
108            .finish()
109    }
110}
111
112impl<const N: u16> RawDict<N> {
113    const _ASSERT: () = assert!(N > 0, "Dict with 0-bit key is invalid");
114
115    /// Creates an empty dictionary.
116    pub const fn new() -> Self {
117        Self(None)
118    }
119
120    /// Builds a dictionary from a sorted collection.
121    pub fn try_from_btree<K, V>(sorted: &BTreeMap<K, V>) -> Result<Self, Error>
122    where
123        K: StoreDictKey + Ord,
124        V: Store,
125    {
126        assert_eq!(K::BITS, N);
127        let root = ok!(build_dict_from_sorted_iter(sorted, Cell::empty_context()));
128        Ok(Self(root))
129    }
130
131    /// Builds a dictionary from a sorted slice.
132    pub fn try_from_sorted_slice<K, V>(sorted: &[(K, V)]) -> Result<Self, Error>
133    where
134        K: StoreDictKey + Ord,
135        V: Store,
136    {
137        assert_eq!(K::BITS, N);
138        let root = ok!(build_dict_from_sorted_iter(
139            sorted.iter().map(|(k, v)| (k, v)),
140            Cell::empty_context()
141        ));
142        Ok(Self(root))
143    }
144
145    /// Returns `true` if the dictionary contains no elements.
146    pub const fn is_empty(&self) -> bool {
147        self.0.is_none()
148    }
149
150    /// Returns the underlying root cell of the dictionary.
151    #[inline]
152    pub const fn root(&self) -> &Option<Cell> {
153        &self.0
154    }
155
156    /// Returns the underlying root cell of the dictionary.
157    #[inline]
158    pub fn into_root(self) -> Option<Cell> {
159        self.0
160    }
161
162    /// Loads a non-empty dictionary from a root cell.
163    #[inline]
164    pub fn load_from_root_ext(
165        slice: &mut CellSlice<'_>,
166        context: &dyn CellContext,
167    ) -> Result<Self, Error> {
168        match dict_load_from_root(slice, N, context) {
169            Ok(root) => Ok(Self(Some(root))),
170            Err(e) => Err(e),
171        }
172    }
173
174    /// Returns a `CellSlice` of the value corresponding to the key.
175    ///
176    /// NOTE: Uses the default cell context.
177    pub fn get<'a>(&'a self, key: CellSlice<'_>) -> Result<Option<CellSlice<'a>>, Error> {
178        dict_get(self.0.as_ref(), N, key, Cell::empty_context())
179    }
180
181    /// Returns a `CellSlice` of the value corresponding to the key.
182    pub fn get_ext<'a, 'c: 'a>(
183        &'a self,
184        key: CellSlice<'_>,
185        context: &'c dyn CellContext,
186    ) -> Result<Option<CellSlice<'a>>, Error> {
187        dict_get(self.0.as_ref(), N, key, context)
188    }
189
190    /// Computes the minimal key in dictionary that is lexicographically greater than `key`,
191    /// and returns it along with associated value as cell slice parts.
192    pub fn get_next_owned(
193        &self,
194        key: CellSlice<'_>,
195        signed: bool,
196    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
197        dict_find_owned(
198            self.0.as_ref(),
199            N,
200            key,
201            DictBound::Max,
202            false,
203            signed,
204            Cell::empty_context(),
205        )
206    }
207
208    /// Get subdict of dictionary by specified key prefix
209    pub fn get_subdict<'a, 'c: 'a>(
210        &'a self,
211        mut prefix: CellSlice<'a>,
212        context: &'c dyn CellContext,
213    ) -> Result<Option<Cell>, Error> {
214        dict_get_subdict(self.0.as_ref(), N, &mut prefix, context)
215    }
216
217    /// Computes the maximal key in dictionary that is lexicographically smaller than `key`,
218    /// and returns it along with associated value as cell slice parts.
219    pub fn get_prev_owned(
220        &self,
221        key: CellSlice<'_>,
222        signed: bool,
223    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
224        dict_find_owned(
225            self.0.as_ref(),
226            N,
227            key,
228            DictBound::Min,
229            false,
230            signed,
231            Cell::empty_context(),
232        )
233    }
234
235    /// Computes the minimal key in dictionary that is lexicographically greater than `key`,
236    /// and returns it along with associated value as cell slice parts.
237    pub fn get_or_next_owned(
238        &self,
239        key: CellSlice<'_>,
240        signed: bool,
241    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
242        dict_find_owned(
243            self.0.as_ref(),
244            N,
245            key,
246            DictBound::Max,
247            true,
248            signed,
249            Cell::empty_context(),
250        )
251    }
252
253    /// Computes the maximal key in dictionary that is lexicographically smaller than `key`,
254    /// and returns it along with associated value as cell slice parts.
255    pub fn get_or_prev_owned(
256        &self,
257        key: CellSlice<'_>,
258        signed: bool,
259    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
260        dict_find_owned(
261            self.0.as_ref(),
262            N,
263            key,
264            DictBound::Min,
265            true,
266            signed,
267            Cell::empty_context(),
268        )
269    }
270
271    /// Returns cell slice parts of the value corresponding to the key.
272    ///
273    /// NOTE: Uses the default cell context.
274    pub fn get_owned(&self, key: CellSlice<'_>) -> Result<Option<CellSliceParts>, Error> {
275        dict_get_owned(self.0.as_ref(), N, key, Cell::empty_context())
276    }
277
278    /// Returns cell slice parts of the value corresponding to the key.
279    pub fn get_owned_ext(
280        &self,
281        key: CellSlice<'_>,
282        context: &dyn CellContext,
283    ) -> Result<Option<CellSliceParts>, Error> {
284        dict_get_owned(self.0.as_ref(), N, key, context)
285    }
286
287    /// Returns the lowest key and a value corresponding to the key.
288    pub fn get_min(&self, signed: bool) -> Result<Option<(CellDataBuilder, CellSlice<'_>)>, Error> {
289        dict_find_bound(
290            self.0.as_ref(),
291            N,
292            DictBound::Min,
293            signed,
294            Cell::empty_context(),
295        )
296    }
297
298    /// Returns the largest key and a value corresponding to the key.
299    pub fn get_max(&self, signed: bool) -> Result<Option<(CellDataBuilder, CellSlice<'_>)>, Error> {
300        dict_find_bound(
301            self.0.as_ref(),
302            N,
303            DictBound::Max,
304            signed,
305            Cell::empty_context(),
306        )
307    }
308
309    /// Finds the specified dict bound and returns a key and a value corresponding to the key.
310    pub fn get_bound(
311        &self,
312        bound: DictBound,
313        signed: bool,
314    ) -> Result<Option<(CellDataBuilder, CellSlice<'_>)>, Error> {
315        dict_find_bound(self.0.as_ref(), N, bound, signed, Cell::empty_context())
316    }
317
318    /// Finds the specified dict bound and returns a key and a value corresponding to the key.
319    pub fn get_bound_ext<'a, 'c: 'a>(
320        &'a self,
321        bound: DictBound,
322        signed: bool,
323        context: &'c dyn CellContext,
324    ) -> Result<Option<(CellDataBuilder, CellSlice<'a>)>, Error> {
325        dict_find_bound(self.0.as_ref(), N, bound, signed, context)
326    }
327
328    /// Returns the lowest key and cell slice parts corresponding to the key.
329    pub fn get_min_owned(
330        &self,
331        signed: bool,
332    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
333        dict_find_bound_owned(
334            self.0.as_ref(),
335            N,
336            DictBound::Min,
337            signed,
338            Cell::empty_context(),
339        )
340    }
341
342    /// Returns the largest key and cell slice parts corresponding to the key.
343    pub fn get_max_owned(
344        &self,
345        signed: bool,
346    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
347        dict_find_bound_owned(
348            self.0.as_ref(),
349            N,
350            DictBound::Max,
351            signed,
352            Cell::empty_context(),
353        )
354    }
355
356    /// Finds the specified dict bound and returns a key and cell slice parts corresponding to the key.
357    pub fn get_bound_owned(
358        &self,
359        bound: DictBound,
360        signed: bool,
361    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
362        dict_find_bound_owned(self.0.as_ref(), N, bound, signed, Cell::empty_context())
363    }
364
365    /// Finds the specified dict bound and returns a key and cell slice parts corresponding to the key.
366    pub fn get_bound_owned_ext(
367        &self,
368        bound: DictBound,
369        signed: bool,
370        context: &dyn CellContext,
371    ) -> Result<Option<(CellDataBuilder, CellSliceParts)>, Error> {
372        dict_find_bound_owned(self.0.as_ref(), N, bound, signed, context)
373    }
374
375    /// Returns `true` if the dictionary contains a value for the specified key.
376    pub fn contains_key(&self, key: CellSlice<'_>) -> Result<bool, Error> {
377        Ok(ok!(dict_get(self.0.as_ref(), N, key, Cell::empty_context())).is_some())
378    }
379
380    /// Sets the value associated with the key in the dictionary.
381    pub fn set_ext(
382        &mut self,
383        mut key: CellSlice<'_>,
384        value: &dyn Store,
385        context: &dyn CellContext,
386    ) -> Result<bool, Error> {
387        dict_insert(&mut self.0, &mut key, N, &value, SetMode::Set, context)
388    }
389
390    /// Sets the value associated with the key in the dictionary
391    /// only if the key was already present in it.
392    pub fn replace_ext(
393        &mut self,
394        mut key: CellSlice<'_>,
395        value: &dyn Store,
396        context: &dyn CellContext,
397    ) -> Result<bool, Error> {
398        dict_insert(&mut self.0, &mut key, N, value, SetMode::Replace, context)
399    }
400
401    /// Sets the value associated with key in dictionary,
402    /// but only if it is not already present.
403    pub fn add_ext(
404        &mut self,
405        mut key: CellSlice<'_>,
406        value: &dyn Store,
407        context: &dyn CellContext,
408    ) -> Result<bool, Error> {
409        dict_insert(&mut self.0, &mut key, N, value, SetMode::Add, context)
410    }
411
412    /// Removes the value associated with key in dictionary.
413    /// Returns an optional removed value as cell slice parts.
414    pub fn remove_ext(
415        &mut self,
416        mut key: CellSlice<'_>,
417        context: &dyn CellContext,
418    ) -> Result<Option<CellSliceParts>, Error> {
419        dict_remove_owned(&mut self.0, &mut key, N, false, context)
420    }
421
422    /// Removes the specified dict bound.
423    /// Returns an optional removed key and value as cell slice parts.
424    pub fn remove_bound_ext(
425        &mut self,
426        bound: DictBound,
427        signed: bool,
428        context: &dyn CellContext,
429    ) -> Result<Option<DictOwnedEntry>, Error> {
430        dict_remove_bound_owned(&mut self.0, N, bound, signed, context)
431    }
432
433    /// Split dictionary into 2 dictionaries by the first key bit.
434    pub fn split(&self) -> Result<(Self, Self), Error> {
435        self.split_by_prefix_ext(&Default::default(), Cell::empty_context())
436    }
437
438    /// Split dictionary into 2 dictionaries by the first key bit.
439    pub fn split_ext(&self, context: &dyn CellContext) -> Result<(Self, Self), Error> {
440        self.split_by_prefix_ext(&Default::default(), context)
441    }
442
443    /// Split dictionary into 2 dictionaries at the prefix.
444    pub fn split_by_prefix(&self, key_prefix: &CellSlice<'_>) -> Result<(Self, Self), Error> {
445        self.split_by_prefix_ext(key_prefix, Cell::empty_context())
446    }
447
448    /// Split dictionary into 2 dictionaries at the prefix.
449    pub fn split_by_prefix_ext(
450        &self,
451        key_prefix: &CellSlice<'_>,
452        context: &dyn CellContext,
453    ) -> Result<(Self, Self), Error> {
454        let (left, right) = ok!(dict_split_by_prefix(
455            self.0.as_ref(),
456            N,
457            key_prefix,
458            context
459        ));
460        Ok((Self(left), Self(right)))
461    }
462
463    /// Gets an iterator over the entries of the dictionary, sorted by key.
464    /// The iterator element type is `Result<(CellDataBuilder, CellSlice)>`.
465    ///
466    /// If the dictionary is invalid, finishes after the first invalid element,
467    /// returning an error.
468    ///
469    /// # Performance
470    ///
471    /// In the current implementation, iterating over dictionary builds a key
472    /// for each element. Use [`values`] if you don't need keys from an iterator.
473    ///
474    /// [`values`]: RawDict::values
475    pub fn iter(&'_ self) -> RawIter<'_> {
476        RawIter::new(&self.0, N)
477    }
478
479    /// Gets an iterator over the entries of two dictionaries, sorted by key.
480    /// The iterator element type is
481    /// `Result<(CellDataBuilder, Option<CellSlice>, Option<CellSlice>)>`.
482    /// Where the first element is the key, the second is the value from the first dictionary,
483    /// and the third is the value from the second dictionary.
484    ///
485    /// If the dictionary is invalid, finishes after the first invalid element,
486    /// returning an error.
487    ///
488    /// # Performance
489    ///
490    /// In the current implementation, iterating over dictionary builds a key
491    /// for each element.
492    pub fn iter_union<'a>(&'a self, other: &'a RawDict<N>) -> UnionRawIter<'a> {
493        UnionRawIter::new(&self.0, &other.0, N)
494    }
495
496    /// Gets an iterator over the owned entries of the dictionary, sorted by key.
497    /// The iterator element type is `Result<(CellDataBuilder, CellSliceParts)>`.
498    ///
499    /// If the dictionary is invalid, finishes after the first invalid element,
500    /// returning an error.
501    ///
502    /// # Performance
503    ///
504    /// In the current implementation, iterating over dictionary builds a key
505    /// for each element. Use [`values_owned`] if you don't need keys from an iterator.
506    ///
507    /// [`values_owned`]: RawDict::values_owned
508    pub fn iter_owned(&'_ self) -> RawOwnedIter<'_> {
509        RawOwnedIter::new(&self.0, N)
510    }
511
512    /// Gets an iterator over the keys of the dictionary, in sorted order.
513    /// The iterator element type is `Result<CellDataBuilder>`.
514    ///
515    /// If the dictionary is invalid, finishes after the first invalid element,
516    /// returning an error.
517    ///
518    /// # Performance
519    ///
520    /// In the current implementation, iterating over dictionary builds a key
521    /// for each element. Use [`values`] if you don't need keys from an iterator.
522    ///
523    /// [`values`]: RawDict::values
524    pub fn keys(&'_ self) -> RawKeys<'_> {
525        RawKeys::new(&self.0, N)
526    }
527
528    /// Gets an iterator over the values of the dictionary, in order by key.
529    /// The iterator element type is `Result<CellSlice>`.
530    ///
531    /// If the dictionary is invalid, finishes after the first invalid element,
532    /// returning an error.
533    pub fn values(&'_ self) -> RawValues<'_> {
534        RawValues::new(&self.0, N)
535    }
536
537    /// Gets an iterator over the owned values of the dictionary, in order by key.
538    /// The iterator element type is `Result<CellSliceParts>`.
539    ///
540    /// If the dictionary is invalid, finishes after the first invalid element,
541    /// returning an error.
542    pub fn values_owned(&'_ self) -> RawOwnedValues<'_> {
543        RawOwnedValues::new(&self.0, N)
544    }
545
546    /// Sets the value associated with the key in the dictionary.
547    ///
548    /// Use [`set_ext`] if you need to use a custom cell context.
549    ///
550    /// [`set_ext`]: RawDict::set_ext
551    pub fn set<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
552        self.set_ext(key, &value, Cell::empty_context())
553    }
554
555    /// Sets the value associated with the key in the dictionary
556    /// only if the key was already present in it.
557    ///
558    /// Use [`replace_ext`] if you need to use a custom cell context.
559    ///
560    /// [`replace_ext`]: RawDict::replace_ext
561    pub fn replace<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
562        self.replace_ext(key, &value, Cell::empty_context())
563    }
564
565    /// Sets the value associated with key in dictionary,
566    /// but only if it is not already present.
567    ///
568    /// Use [`add_ext`] if you need to use a custom cell context.
569    ///
570    /// [`add_ext`]: RawDict::add_ext
571    pub fn add<T: Store>(&mut self, key: CellSlice<'_>, value: T) -> Result<bool, Error> {
572        self.add_ext(key, &value, Cell::empty_context())
573    }
574
575    /// Removes the value associated with key in dictionary.
576    /// Returns an optional removed value as cell slice parts.
577    ///
578    /// Use [`remove_ext`] if you need to use a custom cell context.
579    ///
580    /// [`remove_ext`]: RawDict::remove_ext
581    pub fn remove(&mut self, key: CellSlice<'_>) -> Result<Option<CellSliceParts>, Error> {
582        self.remove_ext(key, Cell::empty_context())
583    }
584
585    /// Removes the lowest key from the dict.
586    /// Returns an optional removed key and value as cell slice parts.
587    ///
588    /// Use [`remove_bound_ext`] if you need to use a custom context.
589    ///
590    /// [`remove_bound_ext`]: RawDict::remove_bound_ext
591    pub fn remove_min(&mut self, signed: bool) -> Result<Option<DictOwnedEntry>, Error> {
592        self.remove_bound_ext(DictBound::Min, signed, Cell::empty_context())
593    }
594
595    /// Removes the largest key from the dict.
596    /// Returns an optional removed key and value as cell slice parts.
597    ///
598    /// Use [`remove_bound_ext`] if you need to use a custom cell context.
599    ///
600    /// [`remove_bound_ext`]: RawDict::remove_bound_ext
601    pub fn remove_max(&mut self, signed: bool) -> Result<Option<DictOwnedEntry>, Error> {
602        self.remove_bound_ext(DictBound::Max, signed, Cell::empty_context())
603    }
604
605    /// Removes the specified dict bound.
606    /// Returns an optional removed key and value as cell slice parts.
607    ///
608    /// Use [`remove_bound_ext`] if you need to use a custom cell context.
609    ///
610    /// [`remove_bound_ext`]: RawDict::remove_bound_ext
611    pub fn remove_bound(
612        &mut self,
613        bound: DictBound,
614        signed: bool,
615    ) -> Result<Option<DictOwnedEntry>, Error> {
616        self.remove_bound_ext(bound, signed, Cell::empty_context())
617    }
618}
619
620/// An iterator over the owned entries of a [`RawDict`].
621///
622/// This struct is created by the [`iter_owned`] method on [`RawDict`].
623/// See its documentation for more.
624///
625/// [`iter_owned`]: RawDict::iter_owned
626#[derive(Clone)]
627pub struct RawOwnedIter<'a> {
628    root: &'a Option<Cell>,
629    inner: RawIter<'a>,
630}
631
632impl<'a> RawOwnedIter<'a> {
633    /// Creates an iterator over the owned entries of a dictionary.
634    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
635        Self {
636            inner: RawIter::new(root, bit_len),
637            root,
638        }
639    }
640
641    /// Creates an iterator over the entries of a dictionary with explicit
642    /// direction and behavior.
643    pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
644        Self {
645            inner: RawIter::new_ext(root, bit_len, reversed, signed),
646            root,
647        }
648    }
649
650    /// Changes the direction of the iterator to descending.
651    #[inline]
652    pub fn reversed(mut self) -> Self {
653        self.inner.reversed = true;
654        self
655    }
656
657    /// Changes the behavior of the iterator to reverse the high bit.
658    #[inline]
659    pub fn signed(mut self) -> Self {
660        self.inner.signed = true;
661        self
662    }
663
664    /// Returns whether the iterator direction was reversed.
665    #[inline]
666    pub fn is_reversed(&self) -> bool {
667        self.inner.reversed
668    }
669
670    /// Returns whether the iterator treats keys as signed integers.
671    #[inline]
672    pub fn is_signed(&self) -> bool {
673        self.inner.signed
674    }
675}
676
677impl Iterator for RawOwnedIter<'_> {
678    type Item = Result<(CellDataBuilder, CellSliceParts), Error>;
679
680    fn next(&mut self) -> Option<Self::Item> {
681        self.inner.next_owned(self.root)
682    }
683}
684
685/// An iterator over the entries of a [`RawDict`] or a [`Dict`].
686///
687/// This struct is created by the [`iter`] method on [`RawDict`] or the [`raw_iter`] method on [`Dict`].
688/// See their documentation for more.
689///
690/// [`Dict`]: crate::dict::Dict
691/// [`iter`]: RawDict::iter
692/// [`raw_iter`]: crate::dict::Dict::raw_iter
693#[derive(Clone)]
694pub struct RawIter<'a> {
695    segments: Vec<IterSegment<'a>>,
696    status: IterStatus,
697    builder: Box<CellDataBuilder>,
698    reversed: bool,
699    signed: bool,
700}
701
702impl<'a> RawIter<'a> {
703    /// Creates an iterator over the entries of a dictionary.
704    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
705        Self::new_ext(root, bit_len, false, false)
706    }
707
708    /// Creates an iterator over the entries of a dictionary with explicit
709    /// direction and behavior.
710    pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
711        let mut segments = Vec::new();
712
713        // Push root segment if any
714        if let Some(root) = root {
715            let Ok(data) = root.as_slice() else {
716                return Self {
717                    segments: Vec::new(),
718                    status: IterStatus::UnexpectedCell,
719                    builder: Box::default(),
720                    reversed,
721                    signed,
722                };
723            };
724
725            segments.push(IterSegment {
726                data,
727                remaining_bit_len: bit_len,
728                prefix: None,
729            });
730        }
731
732        Self {
733            segments,
734            status: IterStatus::Valid,
735            builder: Default::default(),
736            reversed,
737            signed,
738        }
739    }
740
741    /// Changes the direction of the iterator to descending.
742    #[inline]
743    pub fn reversed(mut self) -> Self {
744        self.reversed = true;
745        self
746    }
747
748    /// Changes the behavior of the iterator to reverse the high bit.
749    #[inline]
750    pub fn signed(mut self) -> Self {
751        self.signed = true;
752        self
753    }
754
755    /// Returns whether the iterator direction was reversed.
756    #[inline]
757    pub fn is_reversed(&self) -> bool {
758        self.reversed
759    }
760
761    /// Returns whether the iterator treats keys as signed integers.
762    #[inline]
763    pub fn is_signed(&self) -> bool {
764        self.signed
765    }
766
767    /// Advances the iterator and returns the next value as owned cell slice parts.
768    pub fn next_owned(
769        &mut self,
770        root: &Option<Cell>,
771    ) -> Option<Result<(CellDataBuilder, CellSliceParts), Error>> {
772        Some(match self.next()? {
773            Ok((key, slice)) => {
774                let parent = match self.segments.last() {
775                    Some(segment) => {
776                        let refs_offset = segment.data.offset_refs();
777                        debug_assert!(
778                            segment.prefix.is_some() && (refs_offset == 1 || refs_offset == 2)
779                        );
780
781                        let next_bit = (refs_offset != 1)
782                            ^ self.reversed
783                            ^ (self.signed
784                                && self.segments.len() == 1
785                                && segment.prefix.unwrap().is_data_empty());
786
787                        match segment.data.cell().reference_cloned(next_bit as u8) {
788                            Some(cell) => cell,
789                            None => return Some(Err(self.finish(Error::CellUnderflow))),
790                        }
791                    }
792                    None => match root {
793                        Some(root) => root.clone(),
794                        None => {
795                            debug_assert!(false, "Non-empty iterator for empty dict");
796                            unsafe { std::hint::unreachable_unchecked() };
797                        }
798                    },
799                };
800                Ok((key, (slice.range(), parent)))
801            }
802            Err(e) => Err(e),
803        })
804    }
805
806    #[inline]
807    pub(crate) fn finish(&mut self, err: Error) -> Error {
808        self.status = IterStatus::Broken;
809        err
810    }
811}
812
813impl<'a> Iterator for RawIter<'a> {
814    type Item = Result<(CellDataBuilder, CellSlice<'a>), Error>;
815
816    fn next(&mut self) -> Option<Self::Item> {
817        if unlikely(!self.status.is_valid()) {
818            return if self.status.is_unexpected_cell() {
819                self.status = IterStatus::Broken;
820                Some(Err(Error::UnexpectedExoticCell))
821            } else {
822                None
823            };
824        }
825
826        fn next_impl<'a>(
827            reverse: bool,
828            signed: bool,
829            segments: &mut Vec<IterSegment<'a>>,
830            builder: &mut CellDataBuilder,
831        ) -> Result<Option<(CellDataBuilder, CellSlice<'a>)>, Error> {
832            #[allow(clippy::never_loop)]
833            loop {
834                let mut to_rewind = 0;
835                let segment = loop {
836                    let is_root = segments.len() == 1;
837                    let Some(segment) = segments.last_mut() else {
838                        return Ok(None);
839                    };
840
841                    // Handle root case
842                    let Some(prefix) = &segment.prefix else {
843                        break segment;
844                    };
845
846                    let refs_offset = segment.data.offset_refs();
847                    if refs_offset < 2 {
848                        // Found the latest unprocessed slice
849                        let remaining_bit_len = segment.remaining_bit_len;
850                        let next_bit = (refs_offset != 0)
851                            ^ reverse
852                            ^ (signed && is_root && prefix.is_data_empty());
853
854                        let data = ok!(segment.data.cell().get_reference_as_slice(next_bit as u8));
855                        segment.data.skip_first(0, 1).ok();
856
857                        ok!(builder.rewind_bits(to_rewind));
858                        ok!(builder.store_bit(next_bit));
859                        segments.push(IterSegment {
860                            data,
861                            prefix: None,
862                            remaining_bit_len,
863                        });
864                        // SAFETY: we have just added a new element
865                        break unsafe { segments.last_mut().unwrap_unchecked() };
866                    } else {
867                        // Rewind prefix
868                        to_rewind += prefix.size_bits();
869                        // Pop processed segments
870                        segments.pop();
871                        // Rewind reference bit (if any)
872                        to_rewind += !segments.is_empty() as u16;
873                    }
874                };
875
876                // Read the next key part from the latest segment
877                let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
878
879                // Check remaining bits
880                return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
881                    // Return value if there are no remaining bits to read
882                    Some(0) => {
883                        // Try to store the last prefix into the result key
884                        let mut key = builder.clone();
885                        ok!(key.store_slice_data(prefix));
886
887                        let data = segment.data;
888
889                        // Pop the current segment from the stack
890                        segments.pop();
891                        ok!(builder.rewind_bits(!segments.is_empty() as u16));
892
893                        Ok(Some((key, data)))
894                    }
895                    // Append prefix to builder and proceed to the next segment
896                    Some(remaining) => {
897                        if segment.data.size_refs() < 2 {
898                            return Err(Error::CellUnderflow);
899                        }
900
901                        // Try to store the next prefix into the buffer
902                        ok!(builder.store_slice_data(prefix));
903
904                        // Update segment prefix
905                        segment.prefix = Some(prefix);
906                        segment.remaining_bit_len = remaining - 1;
907
908                        // Handle next segment
909                        continue;
910                    }
911                    None => Err(Error::CellUnderflow),
912                };
913            }
914        }
915
916        match next_impl(
917            self.reversed,
918            self.signed,
919            &mut self.segments,
920            &mut self.builder,
921        ) {
922            Ok(res) => res.map(Ok),
923            Err(e) => Some(Err(self.finish(e))),
924        }
925    }
926}
927
928#[derive(Clone)]
929struct IterSegment<'a> {
930    data: CellSlice<'a>,
931    remaining_bit_len: u16,
932    prefix: Option<CellSlice<'a>>,
933}
934
935/// An iterator over the entries across two [`RawDict`] or two [`Dict`].
936///
937/// This struct is created by the [`iter_union`] method on [`RawDict`]
938/// or the [`raw_iter_union`] method on [`Dict`].
939///
940/// [`Dict`]: crate::dict::Dict
941/// [`iter_union`]: RawDict::iter_union
942/// [`raw_iter_union`]: crate::dict::Dict::raw_iter_union
943#[derive(Clone)]
944pub struct UnionRawIter<'a> {
945    left: RawIter<'a>,
946    left_peeked: Option<Box<(CellDataBuilder, CellSlice<'a>)>>,
947    left_finished: bool,
948    right: RawIter<'a>,
949    right_peeked: Option<Box<(CellDataBuilder, CellSlice<'a>)>>,
950    right_finished: bool,
951}
952
953impl<'a> UnionRawIter<'a> {
954    /// Creates an iterator over the entries of dictionaries.
955    pub fn new(left_root: &'a Option<Cell>, right_root: &'a Option<Cell>, bit_len: u16) -> Self {
956        Self::new_ext(left_root, right_root, bit_len, false, false)
957    }
958
959    /// Creates an iterator over the entries of dictionaries
960    ///  with explicit direction and behavior.
961    pub fn new_ext(
962        left_root: &'a Option<Cell>,
963        right_root: &'a Option<Cell>,
964        bit_len: u16,
965        reversed: bool,
966        signed: bool,
967    ) -> Self {
968        Self {
969            left: RawIter::new_ext(left_root, bit_len, reversed, signed),
970            left_peeked: None,
971            left_finished: false,
972            right: RawIter::new_ext(right_root, bit_len, reversed, signed),
973            right_peeked: None,
974            right_finished: false,
975        }
976    }
977
978    /// Changes the direction of the iterator to descending.
979    #[inline]
980    pub fn reversed(mut self) -> Self {
981        self.left.reversed = true;
982        self.right.reversed = true;
983        self
984    }
985
986    /// Changes the behavior of the iterator to reverse the high bit.
987    #[inline]
988    pub fn signed(mut self) -> Self {
989        self.left.signed = true;
990        self.right.signed = true;
991        self
992    }
993
994    /// Returns whether the iterator direction was reversed.
995    #[inline]
996    pub fn is_reversed(&self) -> bool {
997        self.left.reversed
998    }
999
1000    /// Returns whether the iterator treats keys as signed integers.
1001    #[inline]
1002    pub fn is_signed(&self) -> bool {
1003        self.left.signed
1004    }
1005
1006    #[inline]
1007    pub(crate) fn finish(&mut self, err: Error) -> Error {
1008        self.left.status = IterStatus::Broken;
1009        self.right.status = IterStatus::Broken;
1010        err
1011    }
1012
1013    fn peek<'p>(
1014        iter: &mut RawIter<'a>,
1015        finished: &mut bool,
1016        peeked: &'p mut Option<Box<(CellDataBuilder, CellSlice<'a>)>>,
1017    ) -> Result<Option<&'p (CellDataBuilder, CellSlice<'a>)>, Error> {
1018        if !*finished && peeked.is_none() {
1019            match iter.next() {
1020                Some(Ok(next)) => {
1021                    *peeked = Some(Box::new(next));
1022                }
1023                Some(Err(e)) => {
1024                    *finished = true;
1025                    return Err(e);
1026                }
1027                None => *finished = true,
1028            }
1029        }
1030        Ok(peeked.as_deref())
1031    }
1032}
1033
1034impl<'a> Iterator for UnionRawIter<'a> {
1035    type Item = Result<
1036        (
1037            CellDataBuilder,
1038            Option<CellSlice<'a>>,
1039            Option<CellSlice<'a>>,
1040        ),
1041        Error,
1042    >;
1043
1044    fn next(&mut self) -> Option<Self::Item> {
1045        if unlikely(!self.left.status.is_valid() || !self.right.status.is_valid()) {
1046            if !self.left.status.is_unexpected_cell() && !self.right.status.is_unexpected_cell() {
1047                return None;
1048            }
1049
1050            self.left.status = IterStatus::Broken;
1051            self.right.status = IterStatus::Broken;
1052            return Some(Err(Error::UnexpectedExoticCell));
1053        }
1054
1055        let reversed = self.is_reversed();
1056        let signed = self.is_signed();
1057
1058        let left = match Self::peek(
1059            &mut self.left,
1060            &mut self.left_finished,
1061            &mut self.left_peeked,
1062        ) {
1063            Ok(res) => res,
1064            Err(e) => return Some(Err(self.finish(e))),
1065        };
1066
1067        let right = match Self::peek(
1068            &mut self.right,
1069            &mut self.right_finished,
1070            &mut self.right_peeked,
1071        ) {
1072            Ok(res) => res,
1073            Err(e) => return Some(Err(self.finish(e))),
1074        };
1075
1076        match (left, right) {
1077            (None, None) => None,
1078            (Some((left_key, left_value)), None) => {
1079                let res = Some(Ok((left_key.clone(), Some(*left_value), None)));
1080                self.left_peeked = None;
1081                res
1082            }
1083            (None, Some((right_key, right_value))) => {
1084                let res = Some(Ok((right_key.clone(), None, Some(*right_value))));
1085                self.right_peeked = None;
1086                res
1087            }
1088            (Some((left_key, left_value)), Some((right_key, right_value))) => {
1089                let cmp = {
1090                    let left_key = left_key.as_data_slice();
1091                    let right_key = right_key.as_data_slice();
1092
1093                    let mut reversed = reversed;
1094                    if signed {
1095                        let left_is_neg = left_key.get_bit(0).ok().unwrap_or_default();
1096                        let right_is_neg = right_key.get_bit(0).ok().unwrap_or_default();
1097                        reversed ^= left_is_neg != right_is_neg;
1098                    }
1099
1100                    let cmp = match left_key.lex_cmp(&right_key) {
1101                        Ok(cmp) => cmp,
1102                        Err(e) => return Some(Err(self.finish(e))),
1103                    };
1104
1105                    if reversed {
1106                        cmp.reverse()
1107                    } else {
1108                        cmp
1109                    }
1110                };
1111
1112                match cmp {
1113                    std::cmp::Ordering::Less => {
1114                        let res = Some(Ok((left_key.clone(), Some(*left_value), None)));
1115                        self.left_peeked = None;
1116                        res
1117                    }
1118                    std::cmp::Ordering::Greater => {
1119                        let res = Some(Ok((right_key.clone(), None, Some(*right_value))));
1120                        self.right_peeked = None;
1121                        res
1122                    }
1123                    std::cmp::Ordering::Equal => {
1124                        let res = Some(Ok((
1125                            left_key.clone(),
1126                            Some(*left_value),
1127                            Some(*right_value),
1128                        )));
1129                        self.left_peeked = None;
1130                        self.right_peeked = None;
1131                        res
1132                    }
1133                }
1134            }
1135        }
1136    }
1137}
1138
1139/// An iterator over the keys of a [`RawDict`] or a [`Dict`].
1140///
1141/// This struct is created by the [`keys`] method on [`RawDict`] or the [`raw_keys`] method on [`Dict`].
1142/// See their documentation for more.
1143///
1144/// [`Dict`]: crate::dict::Dict
1145/// [`keys`]: RawDict::keys
1146/// [`raw_keys`]: crate::dict::Dict::raw_keys
1147#[derive(Clone)]
1148pub struct RawKeys<'a> {
1149    inner: RawIter<'a>,
1150}
1151
1152impl<'a> RawKeys<'a> {
1153    /// Creates an iterator over the keys of a dictionary.
1154    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1155        Self {
1156            inner: RawIter::new(root, bit_len),
1157        }
1158    }
1159
1160    /// Creates an iterator over the keys of a dictionary with explicit
1161    /// direction and behavior.
1162    pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1163        Self {
1164            inner: RawIter::new_ext(root, bit_len, reversed, signed),
1165        }
1166    }
1167
1168    /// Changes the direction of the iterator to descending.
1169    #[inline]
1170    pub fn reversed(mut self) -> Self {
1171        self.inner.reversed = true;
1172        self
1173    }
1174
1175    /// Changes the behavior of the iterator to reverse the high bit.
1176    #[inline]
1177    pub fn signed(mut self) -> Self {
1178        self.inner.signed = true;
1179        self
1180    }
1181
1182    /// Returns whether the iterator direction was reversed.
1183    #[inline]
1184    pub fn is_reversed(&self) -> bool {
1185        self.inner.reversed
1186    }
1187
1188    /// Returns whether the iterator treats keys as signed integers.
1189    #[inline]
1190    pub fn is_signed(&self) -> bool {
1191        self.inner.signed
1192    }
1193}
1194
1195impl Iterator for RawKeys<'_> {
1196    type Item = Result<CellDataBuilder, Error>;
1197
1198    fn next(&mut self) -> Option<Self::Item> {
1199        match self.inner.next()? {
1200            Ok((key, _)) => Some(Ok(key)),
1201            Err(e) => Some(Err(e)),
1202        }
1203    }
1204}
1205
1206/// An iterator over the owned values of a [`RawDict`].
1207///
1208/// This struct is created by the [`values_owned`] method on [`RawDict`].
1209/// See its documentation for more.
1210///
1211/// [`values_owned`]: RawDict::values_owned
1212#[derive(Clone)]
1213pub struct RawOwnedValues<'a> {
1214    root: &'a Option<Cell>,
1215    inner: RawValues<'a>,
1216}
1217
1218impl<'a> RawOwnedValues<'a> {
1219    /// Creates an iterator over the owned entries of a dictionary.
1220    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1221        Self {
1222            inner: RawValues::new(root, bit_len),
1223            root,
1224        }
1225    }
1226
1227    /// Creates an iterator over the values of a dictionary with explicit
1228    /// direction and behavior.
1229    pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1230        Self {
1231            inner: RawValues::new_ext(root, bit_len, reversed, signed),
1232            root,
1233        }
1234    }
1235
1236    /// Changes the direction of the iterator to descending.
1237    #[inline]
1238    pub fn reversed(mut self) -> Self {
1239        self.inner.reversed = true;
1240        self
1241    }
1242
1243    /// Changes the behavior of the iterator to reverse the high bit.
1244    #[inline]
1245    pub fn signed(mut self) -> Self {
1246        self.inner.signed = true;
1247        self
1248    }
1249
1250    /// Returns whether the iterator direction was reversed.
1251    #[inline]
1252    pub fn is_reversed(&self) -> bool {
1253        self.inner.reversed
1254    }
1255
1256    /// Returns whether the iterator treats keys as signed integers.
1257    #[inline]
1258    pub fn is_signed(&self) -> bool {
1259        self.inner.signed
1260    }
1261}
1262
1263impl Iterator for RawOwnedValues<'_> {
1264    type Item = Result<CellSliceParts, Error>;
1265
1266    fn next(&mut self) -> Option<Self::Item> {
1267        Some(match self.inner.next()? {
1268            Ok(slice) => {
1269                let parent = match self.inner.segments.last() {
1270                    Some(segment) => {
1271                        let refs_offset = segment.data.offset_refs();
1272                        debug_assert!(refs_offset > 0);
1273                        match segment.data.cell().reference_cloned(refs_offset - 1) {
1274                            Some(cell) => cell,
1275                            None => return Some(Err(self.inner.finish(Error::CellUnderflow))),
1276                        }
1277                    }
1278                    None => match self.root {
1279                        Some(root) => root.clone(),
1280                        None => {
1281                            debug_assert!(false, "Non-empty iterator for empty dict");
1282                            unsafe { std::hint::unreachable_unchecked() };
1283                        }
1284                    },
1285                };
1286                Ok((slice.range(), parent))
1287            }
1288            Err(e) => Err(e),
1289        })
1290    }
1291}
1292
1293/// An iterator over the values of a [`RawDict`] or a [`Dict`].
1294///
1295/// This struct is created by the [`values`] method on [`RawDict`] or the [`raw_values`] method on [`Dict`].
1296/// See their documentation for more.
1297///
1298/// [`Dict`]: crate::dict::Dict
1299/// [`values`]: RawDict::values
1300/// [`raw_values`]: crate::dict::Dict::raw_values
1301#[derive(Clone)]
1302pub struct RawValues<'a> {
1303    segments: Vec<ValuesSegment<'a>>,
1304    status: IterStatus,
1305    reversed: bool,
1306    signed: bool,
1307}
1308
1309impl<'a> RawValues<'a> {
1310    /// Creates an iterator over the values of a dictionary.
1311    pub fn new(root: &'a Option<Cell>, bit_len: u16) -> Self {
1312        Self::new_ext(root, bit_len, false, false)
1313    }
1314
1315    /// Creates an iterator over the values of a dictionary with explicit
1316    /// direction and behavior.
1317    pub fn new_ext(root: &'a Option<Cell>, bit_len: u16, reversed: bool, signed: bool) -> Self {
1318        let mut segments = Vec::new();
1319        if let Some(root) = root {
1320            let Ok(data) = root.as_slice() else {
1321                return Self {
1322                    segments: Vec::new(),
1323                    status: IterStatus::UnexpectedCell,
1324                    reversed,
1325                    signed,
1326                };
1327            };
1328
1329            segments.push(ValuesSegment {
1330                data,
1331                remaining_bit_len: bit_len,
1332            });
1333        }
1334        Self {
1335            segments,
1336            status: IterStatus::Valid,
1337            reversed,
1338            signed,
1339        }
1340    }
1341
1342    /// Changes the direction of the iterator to descending.
1343    #[inline]
1344    pub fn reversed(mut self) -> Self {
1345        self.reversed = true;
1346        self
1347    }
1348
1349    /// Changes the behavior of the iterator to reverse the high bit.
1350    #[inline]
1351    pub fn signed(mut self) -> Self {
1352        self.signed = true;
1353        self
1354    }
1355
1356    /// Returns whether the iterator direction was reversed.
1357    #[inline]
1358    pub fn is_reversed(&self) -> bool {
1359        self.reversed
1360    }
1361
1362    /// Returns whether the iterator treats keys as signed integers.
1363    #[inline]
1364    pub fn is_signed(&self) -> bool {
1365        self.signed
1366    }
1367
1368    #[inline]
1369    pub(crate) fn finish(&mut self, err: Error) -> Error {
1370        self.status = IterStatus::Broken;
1371        err
1372    }
1373}
1374
1375impl<'a> Iterator for RawValues<'a> {
1376    type Item = Result<CellSlice<'a>, Error>;
1377
1378    fn next(&mut self) -> Option<Self::Item> {
1379        if unlikely(!self.status.is_valid()) {
1380            return if self.status.is_unexpected_cell() {
1381                self.status = IterStatus::Broken;
1382                Some(Err(Error::UnexpectedExoticCell))
1383            } else {
1384                None
1385            };
1386        }
1387
1388        fn next_impl<'a>(
1389            reverse: bool,
1390            signed: bool,
1391            segments: &mut Vec<ValuesSegment<'a>>,
1392        ) -> Result<Option<CellSlice<'a>>, Error> {
1393            #[allow(clippy::never_loop)]
1394            loop {
1395                // Find the latest slice which has not been loaded yet
1396                let segment = loop {
1397                    let is_root = segments.len() == 1;
1398                    let Some(segment) = segments.last_mut() else {
1399                        return Ok(None);
1400                    };
1401
1402                    if segment.data.offset_bits() == 0 {
1403                        break segment;
1404                    }
1405
1406                    let refs_offset = segment.data.offset_refs();
1407                    if refs_offset < 2 {
1408                        // Found the latest unprocessed slice
1409                        let remaining_bit_len = segment.remaining_bit_len;
1410                        let next_bit = (refs_offset != 0)
1411                            ^ reverse
1412                            ^ (signed && is_root && segment.data.is_data_empty());
1413                        let data = ok!(segment.data.cell().get_reference_as_slice(next_bit as u8));
1414                        segment.data.skip_first(0, 1).ok();
1415
1416                        segments.push(ValuesSegment {
1417                            data,
1418                            remaining_bit_len,
1419                        });
1420                        // SAFETY: we have just added a new element
1421                        break unsafe { segments.last_mut().unwrap_unchecked() };
1422                    } else {
1423                        segments.pop();
1424                    }
1425                };
1426
1427                // Read the next key part from the latest segment
1428                let prefix = ok!(read_label(&mut segment.data, segment.remaining_bit_len));
1429
1430                // Check remaining bits
1431                return match segment.remaining_bit_len.checked_sub(prefix.size_bits()) {
1432                    // Return value if there are no remaining bits to read
1433                    Some(0) => {
1434                        let data = segment.data;
1435                        // Pop the current segment from the stack
1436                        segments.pop();
1437                        Ok(Some(data))
1438                    }
1439                    // Append prefix to builder and proceed to the next segment
1440                    Some(remaining) => {
1441                        if segment.data.size_refs() < 2 {
1442                            return Err(Error::CellUnderflow);
1443                        }
1444                        segment.remaining_bit_len = remaining - 1;
1445                        // Handle next segment
1446                        continue;
1447                    }
1448                    None => Err(Error::CellUnderflow),
1449                };
1450            }
1451        }
1452
1453        match next_impl(self.reversed, self.signed, &mut self.segments) {
1454            Ok(res) => res.map(Ok),
1455            Err(e) => Some(Err(self.finish(e))),
1456        }
1457    }
1458}
1459
1460#[derive(Copy, Clone)]
1461struct ValuesSegment<'a> {
1462    data: CellSlice<'a>,
1463    remaining_bit_len: u16,
1464}
1465
1466#[cfg(test)]
1467mod tests {
1468
1469    use super::*;
1470    use crate::prelude::*;
1471
1472    fn build_cell<F: FnOnce(&mut CellBuilder) -> Result<(), Error>>(f: F) -> Cell {
1473        let mut builder = CellBuilder::new();
1474        f(&mut builder).unwrap();
1475        builder.build().unwrap()
1476    }
1477
1478    #[test]
1479    fn dict_set() -> anyhow::Result<()> {
1480        let mut dict = RawDict::<32>::new();
1481
1482        let key = CellBuilder::build_from(123u32)?;
1483
1484        dict.set(key.as_slice()?, ())?;
1485        {
1486            let mut values = dict.values();
1487            let value = values.next().unwrap().unwrap();
1488            assert!(value.is_data_empty() && value.is_refs_empty());
1489            assert!(values.next().is_none());
1490        }
1491
1492        dict.set(key.as_slice()?, 0xffffu16)?;
1493        {
1494            let mut values = dict.values();
1495            let mut value = values.next().unwrap()?;
1496            assert_eq!(value.load_u16(), Ok(0xffff));
1497            assert!(value.is_data_empty() && value.is_refs_empty());
1498            assert!(values.next().is_none());
1499        }
1500
1501        Ok(())
1502    }
1503
1504    #[test]
1505    #[cfg_attr(miri, ignore)] // takes too long to execute on miri
1506    fn dict_set_complex() -> anyhow::Result<()> {
1507        let mut dict = RawDict::<32>::new();
1508        for i in 0..520 {
1509            let key = build_cell(|b| b.store_u32(i));
1510            dict.set(key.as_slice()?, true)?;
1511
1512            let mut total = 0;
1513            for (i, item) in dict.iter().enumerate() {
1514                total += 1;
1515                let (key, value) = item?;
1516                assert_eq!(key.size_bits(), 32);
1517                assert_eq!(value.size_bits(), 1);
1518                let key = key.as_data_slice().load_u32()?;
1519                assert_eq!(key, i as u32);
1520            }
1521            assert_eq!(total, i + 1);
1522        }
1523
1524        Ok(())
1525    }
1526
1527    #[test]
1528    fn dict_replace() -> anyhow::Result<()> {
1529        let mut dict = RawDict::<32>::new();
1530
1531        //
1532        dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1533            .unwrap();
1534        assert!(!dict
1535            .contains_key(build_cell(|b| b.store_u32(123)).as_slice()?)
1536            .unwrap());
1537
1538        //
1539        dict.set(build_cell(|b| b.store_u32(123)).as_slice()?, false)
1540            .unwrap();
1541        dict.replace(build_cell(|b| b.store_u32(123)).as_slice()?, true)
1542            .unwrap();
1543
1544        let mut value = dict
1545            .get(build_cell(|b| b.store_u32(123)).as_slice()?)
1546            .unwrap()
1547            .unwrap();
1548        assert_eq!(value.size_bits(), 1);
1549        assert_eq!(value.load_bit(), Ok(true));
1550
1551        Ok(())
1552    }
1553
1554    #[test]
1555    fn dict_add() -> anyhow::Result<()> {
1556        let mut dict = RawDict::<32>::new();
1557
1558        let key = build_cell(|b| b.store_u32(123));
1559
1560        //
1561        dict.add(key.as_slice()?, false)?;
1562        let mut value = dict.get(key.as_slice()?)?.unwrap();
1563        assert_eq!(value.size_bits(), 1);
1564        assert_eq!(value.load_bit(), Ok(false));
1565
1566        //
1567        dict.add(key.as_slice()?, true)?;
1568        let mut value = dict.get(key.as_slice()?)?.unwrap();
1569        assert_eq!(value.size_bits(), 1);
1570        assert_eq!(value.load_bit(), Ok(false));
1571
1572        Ok(())
1573    }
1574
1575    #[test]
1576    fn dict_split() -> anyhow::Result<()> {
1577        let mut dict = RawDict::<4>::new();
1578        for i in 0..16 {
1579            let key = build_cell(|b| b.store_small_uint(i, 4));
1580            dict.add(key.as_slice()?, i)?;
1581        }
1582
1583        let (left, right) = dict.split()?;
1584        assert!(!left.is_empty());
1585        assert!(!right.is_empty());
1586        assert_eq!(left.iter().count(), 8);
1587        assert_eq!(right.iter().count(), 8);
1588
1589        let (ll, lr) = left.split()?;
1590        assert!(!ll.is_empty());
1591        assert!(lr.is_empty());
1592        assert_eq!(ll.iter().count(), 8);
1593
1594        let (rl, rr) = right.split()?;
1595        assert!(rl.is_empty());
1596        assert!(!rr.is_empty());
1597        assert_eq!(rr.iter().count(), 8);
1598
1599        let (left, right) = RawDict::<4>::new().split()?;
1600        assert!(left.is_empty());
1601        assert!(right.is_empty());
1602
1603        Ok(())
1604    }
1605
1606    #[test]
1607    fn dict_split_by_prefix() -> anyhow::Result<()> {
1608        fn check_range(dict: &RawDict<4>, mut range: std::ops::Range<u8>) {
1609            for key in dict.keys() {
1610                let key = key.unwrap();
1611                let key = key.as_data_slice().load_small_uint(4).unwrap();
1612                assert_eq!(key, range.next().unwrap());
1613            }
1614            assert_eq!(range.next(), None);
1615        }
1616
1617        let mut dict = RawDict::<4>::new();
1618        for i in 0..16 {
1619            let key = build_cell(|b| b.store_small_uint(i, 4));
1620            dict.add(key.as_slice()?, i)?;
1621        }
1622
1623        let (left, right) = dict.split()?;
1624        check_range(&left, 0..8);
1625        check_range(&right, 8..16);
1626
1627        {
1628            let mut prefix = CellBuilder::new();
1629            prefix.store_bit_one()?;
1630            let res = dict.split_by_prefix(&prefix.as_data_slice());
1631            assert!(matches!(res, Err(Error::CellUnderflow)));
1632        }
1633
1634        let (ll, lr) = {
1635            let mut prefix = CellBuilder::new();
1636            prefix.store_bit_zero()?;
1637            left.split_by_prefix(&prefix.as_data_slice())?
1638        };
1639        check_range(&ll, 0..4);
1640        check_range(&lr, 4..8);
1641
1642        let (rl, rr) = {
1643            let mut prefix = CellBuilder::new();
1644            prefix.store_bit_one()?;
1645            right.split_by_prefix(&prefix.as_data_slice())?
1646        };
1647        check_range(&rl, 8..12);
1648        check_range(&rr, 12..16);
1649
1650        Ok(())
1651    }
1652
1653    #[test]
1654    fn dict_get_subdict() -> anyhow::Result<()> {
1655        let mut dict = RawDict::<32>::new();
1656        for i in 0u32..4 {
1657            // let key = i % 2;
1658            let key = CellBuilder::build_from(i)?;
1659            println!("ADDING KEY {}", key.display_data());
1660            dict.add(key.as_slice()?, i)?;
1661        }
1662
1663        let cell = dict.root().as_ref().unwrap();
1664        let boc = Boc::encode_base64(cell);
1665
1666        println!("{}", boc);
1667
1668        let key = CellBuilder::build_from(1u16 << 8)?;
1669
1670        println!("KEY: {}", key.display_data());
1671
1672        let context = &mut SimpleContext::default();
1673
1674        let value: Cell = dict.get_subdict(key.as_slice()?, context)?.unwrap();
1675
1676        print!("{}", value.display_tree());
1677
1678        Ok(())
1679    }
1680
1681    #[test]
1682    fn dict_get() -> anyhow::Result<()> {
1683        let boc =
1684            Boc::decode_base64("te6ccgECOwEAASoAAQHAAQIBIBACAgEgAwMCASAEBAIBIAUFAgEgBgYCASAHBwIBIAgIAgEgCQkCASAoCgIBIAsZAgEgDBsCASArDQIBIA4fAgEgLQ8CASAuIQIBIBERAgEgEhICASATEwIBIBQUAgEgFRUCASAWFgIBIBcXAgEgKBgCASAaGQIBIBsbAgEgHRsCASAcHAIBIB8fAgEgKx4CASAiHwIBICAgAgEgISECASAlJQIBIC0jAgEgLiQCASAvJQIBIDMmAgFiNicCAUg4OAIBICkpAgEgKioCASArKwIBICwsAgEgLS0CASAuLgIBIC8vAgEgMzACAWI2MQIBIDcyAAnWAAAmbwIBIDQ0AgEgNTUCASA2NgIBIDc3AgEgODgCASA5OQIBIDo6AAnQAAAmbw==")?;
1685
1686        // println!("BOC: {}", boc.display_tree());
1687
1688        let dict = boc.parse::<RawDict<32>>()?;
1689
1690        let key = CellBuilder::build_from(u32::from_be_bytes(123u32.to_le_bytes()))?;
1691        let value = dict.get(key.as_slice()?)?.unwrap();
1692
1693        {
1694            let (range, cell) = dict.get_owned(key.as_slice()?)?.unwrap();
1695            assert_eq!(range.apply(&cell).unwrap(), value);
1696        }
1697
1698        let value = {
1699            let mut builder = CellBuilder::new();
1700            builder.store_slice(value)?;
1701            builder.build()?
1702        };
1703        println!("{}", value.display_tree());
1704
1705        Ok(())
1706    }
1707
1708    #[test]
1709    fn dict_iter() -> anyhow::Result<()> {
1710        let boc = Boc::decode_base64("te6ccgEBFAEAeAABAcABAgPOQAUCAgHUBAMACQAAAI3gAAkAAACjoAIBIA0GAgEgCgcCASAJCAAJAAAAciAACQAAAIfgAgEgDAsACQAAAFZgAAkAAABsIAIBIBEOAgEgEA8ACQAAADqgAAkAAABQYAIBIBMSAAkAAAAe4AAJAAAAv2A=")?;
1711        let dict = boc.parse::<RawDict<32>>()?;
1712
1713        let size = dict.values().count();
1714        assert_eq!(size, 10);
1715
1716        let mut rev_iter_items = dict.iter().reversed().collect::<Vec<_>>();
1717        rev_iter_items.reverse();
1718        let mut rev_iter_items = rev_iter_items.into_iter();
1719
1720        for (i, entry) in dict.iter().enumerate() {
1721            let (key, value) = entry?;
1722
1723            let (rev_key, rev_value) = rev_iter_items.next().unwrap().unwrap();
1724            assert_eq!(key, rev_key);
1725            assert_eq!(value.lex_cmp(&rev_value), Ok(std::cmp::Ordering::Equal));
1726
1727            let key = key.as_data_slice().load_u32()?;
1728            assert_eq!(key, i as u32);
1729        }
1730        assert!(rev_iter_items.next().is_none());
1731
1732        let mut last = None;
1733        for (i, entry) in dict.iter_owned().enumerate() {
1734            let (key, (range, cell)) = entry?;
1735
1736            {
1737                let mut slice = range.apply(&cell).unwrap();
1738                assert_eq!(slice.size_bits(), 32);
1739                u32::load_from(&mut slice).unwrap();
1740            }
1741
1742            let key = key.as_data_slice().load_u32()?;
1743            assert_eq!(key, i as u32);
1744            last = Some(key);
1745        }
1746        assert_eq!(last, Some(9));
1747
1748        let mut values_ref = dict.values();
1749        let mut values_owned = dict.values_owned();
1750        for (value_ref, value_owned) in (&mut values_ref).zip(&mut values_owned) {
1751            let value_ref = value_ref.unwrap();
1752            let (range, cell) = value_owned.unwrap();
1753            let value_owned = range.apply(&cell).unwrap();
1754            assert_eq!(
1755                value_ref.lex_cmp(&value_owned),
1756                Ok(std::cmp::Ordering::Equal)
1757            );
1758        }
1759        assert!(values_ref.next().is_none());
1760        assert!(values_owned.next().is_none());
1761
1762        Ok(())
1763    }
1764
1765    #[test]
1766    fn dict_iter_union() -> anyhow::Result<()> {
1767        let mut left = RawDict::<32>::new();
1768        let mut right = RawDict::<32>::new();
1769
1770        // Fill
1771        for i in -4i32..4 {
1772            let key = build_cell(|b| b.store_u32(i as _));
1773            left.set(key.as_slice()?, i)?;
1774        }
1775        for i in -2i32..6 {
1776            let key = build_cell(|b| b.store_u32(i as _));
1777            right.set(key.as_slice()?, i + 100)?;
1778        }
1779
1780        fn compare_iter_values(iter: UnionRawIter<'_>, values: &[(i32, Option<i32>, Option<i32>)]) {
1781            let mut values = values.iter();
1782
1783            for entry in iter {
1784                let (key, left_value, right_value) = entry.unwrap();
1785                let key = key.as_data_slice().load_u32().unwrap() as i32;
1786                let left_value = left_value.map(|v| v.get_u32(0).unwrap() as i32);
1787                let right_value = right_value.map(|v| v.get_u32(0).unwrap() as i32);
1788
1789                assert_eq!(values.next(), Some(&(key, left_value, right_value)));
1790            }
1791            assert_eq!(values.next(), None);
1792        }
1793
1794        // Unsigned
1795        compare_iter_values(left.iter_union(&right), &[
1796            (0, Some(0), Some(100)),
1797            (1, Some(1), Some(101)),
1798            (2, Some(2), Some(102)),
1799            (3, Some(3), Some(103)),
1800            (4, None, Some(104)),
1801            (5, None, Some(105)),
1802            (-4, Some(-4), None),
1803            (-3, Some(-3), None),
1804            (-2, Some(-2), Some(98)),
1805            (-1, Some(-1), Some(99)),
1806        ]);
1807
1808        // Unsigned reversed
1809        compare_iter_values(left.iter_union(&right).reversed(), &[
1810            (-1, Some(-1), Some(99)),
1811            (-2, Some(-2), Some(98)),
1812            (-3, Some(-3), None),
1813            (-4, Some(-4), None),
1814            (5, None, Some(105)),
1815            (4, None, Some(104)),
1816            (3, Some(3), Some(103)),
1817            (2, Some(2), Some(102)),
1818            (1, Some(1), Some(101)),
1819            (0, Some(0), Some(100)),
1820        ]);
1821
1822        // Signed
1823        compare_iter_values(left.iter_union(&right).signed(), &[
1824            (-4, Some(-4), None),
1825            (-3, Some(-3), None),
1826            (-2, Some(-2), Some(98)),
1827            (-1, Some(-1), Some(99)),
1828            (0, Some(0), Some(100)),
1829            (1, Some(1), Some(101)),
1830            (2, Some(2), Some(102)),
1831            (3, Some(3), Some(103)),
1832            (4, None, Some(104)),
1833            (5, None, Some(105)),
1834        ]);
1835
1836        // Signed reversed
1837        compare_iter_values(left.iter_union(&right).signed().reversed(), &[
1838            (5, None, Some(105)),
1839            (4, None, Some(104)),
1840            (3, Some(3), Some(103)),
1841            (2, Some(2), Some(102)),
1842            (1, Some(1), Some(101)),
1843            (0, Some(0), Some(100)),
1844            (-1, Some(-1), Some(99)),
1845            (-2, Some(-2), Some(98)),
1846            (-3, Some(-3), None),
1847            (-4, Some(-4), None),
1848        ]);
1849
1850        Ok(())
1851    }
1852
1853    #[derive(Debug, Default)]
1854    struct SimpleContext {
1855        used_gas: std::cell::Cell<u64>,
1856        loaded_cells: std::cell::RefCell<ahash::HashSet<HashBytes>>,
1857        empty_context: <Cell as CellFamily>::EmptyCellContext,
1858    }
1859
1860    impl SimpleContext {
1861        const BUILD_CELL_GAS: u64 = 500;
1862        const NEW_CELL_GAS: u64 = 100;
1863        const OLD_CELL_GAS: u64 = 25;
1864
1865        fn consume_gas(&self, cell: &DynCell, mode: LoadMode) {
1866            if mode.use_gas() {
1867                let consumed_gas = if self.loaded_cells.borrow_mut().insert(*cell.repr_hash()) {
1868                    Self::NEW_CELL_GAS
1869                } else {
1870                    Self::OLD_CELL_GAS
1871                };
1872
1873                self.used_gas.set(self.used_gas.get() + consumed_gas);
1874            }
1875        }
1876    }
1877
1878    impl CellContext for SimpleContext {
1879        #[inline]
1880        fn finalize_cell(&self, cell: CellParts<'_>) -> Result<Cell, Error> {
1881            self.used_gas
1882                .set(self.used_gas.get() + Self::BUILD_CELL_GAS);
1883            self.empty_context.finalize_cell(cell)
1884        }
1885
1886        #[inline]
1887        fn load_cell(&self, cell: Cell, mode: LoadMode) -> Result<Cell, Error> {
1888            self.consume_gas(cell.as_ref(), mode);
1889            Ok(cell)
1890        }
1891
1892        #[inline]
1893        fn load_dyn_cell<'s: 'a, 'a>(
1894            &self,
1895            cell: &'a DynCell,
1896            mode: LoadMode,
1897        ) -> Result<&'a DynCell, Error> {
1898            self.consume_gas(cell, mode);
1899            Ok(cell)
1900        }
1901    }
1902
1903    #[test]
1904    fn dict_get_gas_usage() -> anyhow::Result<()> {
1905        // Prepare dict
1906        let mut dict = RawDict::<32>::new();
1907        for i in 0..10 {
1908            let mut key = CellBuilder::new();
1909            key.store_u32(i)?;
1910            dict.set(key.as_data_slice(), i)?;
1911        }
1912
1913        // First get
1914        let context = &mut SimpleContext::default();
1915
1916        let mut key = CellBuilder::new();
1917        key.store_u32(5)?;
1918
1919        dict.get_ext(key.as_data_slice(), context)?.unwrap();
1920        assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5);
1921
1922        context.used_gas.set(0);
1923        dict.get_ext(key.as_data_slice(), context)?.unwrap();
1924        assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 5);
1925
1926        // Second get
1927        context.used_gas.set(0);
1928        let mut key = CellBuilder::new();
1929        key.store_u32(9)?;
1930
1931        dict.get_ext(key.as_data_slice(), context)?.unwrap();
1932        assert_eq!(
1933            context.used_gas.get(),
1934            SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
1935        );
1936
1937        context.used_gas.set(0);
1938        dict.get_ext(key.as_data_slice(), context)?.unwrap();
1939        assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 3);
1940
1941        Ok(())
1942    }
1943
1944    #[test]
1945    fn dict_get_owned_gas_usage() -> anyhow::Result<()> {
1946        // Prepare dict
1947        let mut dict = RawDict::<32>::new();
1948        for i in 0..10 {
1949            let mut key = CellBuilder::new();
1950            key.store_u32(i)?;
1951            dict.set(key.as_data_slice(), i)?;
1952        }
1953
1954        // First get
1955        let context = &mut SimpleContext::default();
1956
1957        let mut key = CellBuilder::new();
1958        key.store_u32(5)?;
1959
1960        dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1961        assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5);
1962
1963        context.used_gas.set(0);
1964        dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1965        assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 5);
1966
1967        // Second get
1968        context.used_gas.set(0);
1969        let mut key = CellBuilder::new();
1970        key.store_u32(9)?;
1971
1972        dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1973        assert_eq!(
1974            context.used_gas.get(),
1975            SimpleContext::OLD_CELL_GAS + SimpleContext::NEW_CELL_GAS * 2
1976        );
1977
1978        context.used_gas.set(0);
1979        dict.get_owned_ext(key.as_data_slice(), context)?.unwrap();
1980        assert_eq!(context.used_gas.get(), SimpleContext::OLD_CELL_GAS * 3);
1981
1982        Ok(())
1983    }
1984
1985    #[test]
1986    fn dict_remove_gas_usage() -> anyhow::Result<()> {
1987        let mut dict = RawDict::<32>::new();
1988        for i in 0..10 {
1989            let mut key = CellBuilder::new();
1990            key.store_u32(i)?;
1991            dict.set(key.as_data_slice(), i)?;
1992        }
1993
1994        // Noop remove
1995        let mut key = CellBuilder::new();
1996        key.store_u32(10)?;
1997
1998        let context = &mut SimpleContext::default();
1999        assert!(dict.remove_ext(key.as_data_slice(), context)?.is_none());
2000
2001        assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 2);
2002
2003        // Clear dict
2004        let target_gas = [
2005            SimpleContext::NEW_CELL_GAS * 6 + SimpleContext::BUILD_CELL_GAS * 4,
2006            SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2007            SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2008            SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2009            SimpleContext::NEW_CELL_GAS * 5 + SimpleContext::BUILD_CELL_GAS * 3,
2010            SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2011            SimpleContext::NEW_CELL_GAS * 4 + SimpleContext::BUILD_CELL_GAS * 2,
2012            SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2013            SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS,
2014            SimpleContext::NEW_CELL_GAS,
2015        ];
2016
2017        for i in 0..10 {
2018            println!("===");
2019
2020            let context = &mut SimpleContext::default();
2021
2022            let mut key = CellBuilder::new();
2023            key.store_u32(i)?;
2024
2025            let removed = dict.remove_ext(key.as_data_slice(), context)?;
2026            assert!(removed.is_some());
2027
2028            assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2029        }
2030
2031        Ok(())
2032    }
2033
2034    #[test]
2035    fn dict_remove_bound() -> anyhow::Result<()> {
2036        let make_dict = |range: std::ops::Range<i32>| {
2037            let mut dict = RawDict::<32>::new();
2038            for i in range {
2039                let mut key = CellBuilder::new();
2040                key.store_u32(i as u32)?;
2041                dict.set(key.as_data_slice(), i)?;
2042            }
2043            Ok::<_, anyhow::Error>(dict)
2044        };
2045
2046        let check_range =
2047            |range: std::ops::Range<i32>, bound: DictBound, signed: bool, target_gas: &[u64]| {
2048                let mut dict = make_dict(range.clone())?;
2049                for &target_gas in target_gas {
2050                    println!("=== {range:?} bound={bound:?} signed={signed} [non-owned]");
2051                    let context = &mut SimpleContext::default();
2052                    let (key, _) = dict.get_bound_ext(bound, signed, context)?.unwrap();
2053                    let removed = dict.clone().remove_ext(key.as_data_slice(), context)?;
2054                    assert!(removed.is_some());
2055                    assert_eq!(context.used_gas.get(), target_gas);
2056
2057                    println!("=== {range:?} bound={bound:?} signed={signed} [owned]");
2058                    let context = &mut SimpleContext::default();
2059                    let (key, _) = dict.get_bound_owned_ext(bound, signed, context)?.unwrap();
2060                    let removed = dict.remove_ext(key.as_data_slice(), context)?;
2061                    assert!(removed.is_some());
2062                    assert_eq!(context.used_gas.get(), target_gas);
2063                }
2064
2065                Ok::<_, anyhow::Error>(())
2066            };
2067
2068        // Unsigned MIN
2069        let target_gas = [
2070            SimpleContext::NEW_CELL_GAS * 6
2071                + SimpleContext::OLD_CELL_GAS * 5
2072                + SimpleContext::BUILD_CELL_GAS * 4,
2073            SimpleContext::NEW_CELL_GAS * 5
2074                + SimpleContext::OLD_CELL_GAS * 4
2075                + SimpleContext::BUILD_CELL_GAS * 3,
2076            SimpleContext::NEW_CELL_GAS * 5
2077                + SimpleContext::OLD_CELL_GAS * 4
2078                + SimpleContext::BUILD_CELL_GAS * 3,
2079            SimpleContext::NEW_CELL_GAS * 4
2080                + SimpleContext::OLD_CELL_GAS * 3
2081                + SimpleContext::BUILD_CELL_GAS * 2,
2082            SimpleContext::NEW_CELL_GAS * 5
2083                + SimpleContext::OLD_CELL_GAS * 4
2084                + SimpleContext::BUILD_CELL_GAS * 3,
2085            SimpleContext::NEW_CELL_GAS * 4
2086                + SimpleContext::OLD_CELL_GAS * 3
2087                + SimpleContext::BUILD_CELL_GAS * 2,
2088            SimpleContext::NEW_CELL_GAS * 4
2089                + SimpleContext::OLD_CELL_GAS * 3
2090                + SimpleContext::BUILD_CELL_GAS * 2,
2091            SimpleContext::NEW_CELL_GAS * 3
2092                + SimpleContext::OLD_CELL_GAS * 2
2093                + SimpleContext::BUILD_CELL_GAS,
2094            SimpleContext::NEW_CELL_GAS * 3
2095                + SimpleContext::OLD_CELL_GAS * 2
2096                + SimpleContext::BUILD_CELL_GAS,
2097            SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2098        ];
2099        check_range(0..10, DictBound::Min, false, &target_gas)?;
2100
2101        // Unsigned MAX
2102        let target_gas = [
2103            SimpleContext::NEW_CELL_GAS * 4
2104                + SimpleContext::OLD_CELL_GAS * 3
2105                + SimpleContext::BUILD_CELL_GAS * 2,
2106            SimpleContext::NEW_CELL_GAS * 3
2107                + SimpleContext::OLD_CELL_GAS * 2
2108                + SimpleContext::BUILD_CELL_GAS,
2109            SimpleContext::NEW_CELL_GAS * 5
2110                + SimpleContext::OLD_CELL_GAS * 4
2111                + SimpleContext::BUILD_CELL_GAS * 3,
2112            SimpleContext::NEW_CELL_GAS * 4
2113                + SimpleContext::OLD_CELL_GAS * 3
2114                + SimpleContext::BUILD_CELL_GAS * 2,
2115            SimpleContext::NEW_CELL_GAS * 4
2116                + SimpleContext::OLD_CELL_GAS * 3
2117                + SimpleContext::BUILD_CELL_GAS * 2,
2118            SimpleContext::NEW_CELL_GAS * 3
2119                + SimpleContext::OLD_CELL_GAS * 2
2120                + SimpleContext::BUILD_CELL_GAS,
2121            SimpleContext::NEW_CELL_GAS * 4
2122                + SimpleContext::OLD_CELL_GAS * 3
2123                + SimpleContext::BUILD_CELL_GAS * 2,
2124            SimpleContext::NEW_CELL_GAS * 3
2125                + SimpleContext::OLD_CELL_GAS * 2
2126                + SimpleContext::BUILD_CELL_GAS,
2127            SimpleContext::NEW_CELL_GAS * 3
2128                + SimpleContext::OLD_CELL_GAS * 2
2129                + SimpleContext::BUILD_CELL_GAS,
2130            SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2131        ];
2132        check_range(0..10, DictBound::Max, false, &target_gas)?;
2133
2134        // Signed MIN and MAX
2135        let target_gas = [
2136            SimpleContext::NEW_CELL_GAS * 4
2137                + SimpleContext::OLD_CELL_GAS * 3
2138                + SimpleContext::BUILD_CELL_GAS * 2,
2139            SimpleContext::NEW_CELL_GAS * 5
2140                + SimpleContext::OLD_CELL_GAS * 4
2141                + SimpleContext::BUILD_CELL_GAS * 3,
2142            SimpleContext::NEW_CELL_GAS * 4
2143                + SimpleContext::OLD_CELL_GAS * 3
2144                + SimpleContext::BUILD_CELL_GAS * 2,
2145            SimpleContext::NEW_CELL_GAS * 4
2146                + SimpleContext::OLD_CELL_GAS * 3
2147                + SimpleContext::BUILD_CELL_GAS * 2,
2148            SimpleContext::NEW_CELL_GAS * 3
2149                + SimpleContext::OLD_CELL_GAS * 2
2150                + SimpleContext::BUILD_CELL_GAS,
2151            SimpleContext::NEW_CELL_GAS * 5
2152                + SimpleContext::OLD_CELL_GAS * 4
2153                + SimpleContext::BUILD_CELL_GAS * 3,
2154            SimpleContext::NEW_CELL_GAS * 4
2155                + SimpleContext::OLD_CELL_GAS * 3
2156                + SimpleContext::BUILD_CELL_GAS * 2,
2157            SimpleContext::NEW_CELL_GAS * 4
2158                + SimpleContext::OLD_CELL_GAS * 3
2159                + SimpleContext::BUILD_CELL_GAS * 2,
2160            SimpleContext::NEW_CELL_GAS * 3
2161                + SimpleContext::OLD_CELL_GAS * 2
2162                + SimpleContext::BUILD_CELL_GAS,
2163            SimpleContext::NEW_CELL_GAS + SimpleContext::OLD_CELL_GAS,
2164        ];
2165
2166        // NOTE: same gas for balanced tree
2167        check_range(-5..5, DictBound::Min, true, &target_gas)?;
2168        check_range(-5..5, DictBound::Max, true, &target_gas)?;
2169
2170        Ok(())
2171    }
2172
2173    #[test]
2174    fn dict_insert_gas_usage() -> anyhow::Result<()> {
2175        let target_gas = [
2176            SimpleContext::BUILD_CELL_GAS,
2177            SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2178            SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2179            SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2180            SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2181            SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2182            SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2183            SimpleContext::NEW_CELL_GAS * 3 + SimpleContext::BUILD_CELL_GAS * 5,
2184            SimpleContext::NEW_CELL_GAS + SimpleContext::BUILD_CELL_GAS * 3,
2185            SimpleContext::NEW_CELL_GAS * 2 + SimpleContext::BUILD_CELL_GAS * 4,
2186        ];
2187
2188        // RawDict
2189        let mut dict = RawDict::<32>::new();
2190        for i in 0..10 {
2191            let context = &mut SimpleContext::default();
2192
2193            let mut key = CellBuilder::new();
2194            key.store_u32(i)?;
2195
2196            dict.set_ext(key.as_data_slice(), &i, context)?;
2197
2198            assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2199
2200            println!("===");
2201        }
2202
2203        // Compare `dict_insert` and `dict_insert_owned`
2204        let mut dict = None::<Cell>;
2205        for i in 0..10 {
2206            let mut key = CellBuilder::new();
2207            key.store_u32(i)?;
2208
2209            let context = &mut SimpleContext::default();
2210            let mut old_root = dict.clone();
2211            dict_insert(
2212                &mut dict,
2213                &mut key.as_data_slice(),
2214                32,
2215                &i,
2216                SetMode::Set,
2217                context,
2218            )?;
2219            assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2220
2221            println!("===");
2222
2223            let context = &mut SimpleContext::default();
2224            let expected_new_root = dict.clone();
2225            crate::dict::dict_insert_owned(
2226                &mut old_root,
2227                &mut key.as_data_slice(),
2228                32,
2229                &i,
2230                SetMode::Set,
2231                context,
2232            )?;
2233            assert_eq!(dict, expected_new_root);
2234
2235            assert_eq!(context.used_gas.get(), target_gas[i as usize]);
2236
2237            println!("===");
2238        }
2239
2240        // Check `add` as noop
2241        let mut key = CellBuilder::new();
2242        key.store_u32(5)?;
2243
2244        let context = &mut SimpleContext::default();
2245        dict_insert(
2246            &mut dict,
2247            &mut key.as_data_slice(),
2248            32,
2249            &5u32,
2250            SetMode::Add,
2251            context,
2252        )?;
2253        assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5); // Equivalent to simple get
2254
2255        println!("===");
2256
2257        let context = &mut SimpleContext::default();
2258        crate::dict::dict_insert_owned(
2259            &mut dict,
2260            &mut key.as_data_slice(),
2261            32,
2262            &5u32,
2263            SetMode::Add,
2264            context,
2265        )?;
2266        assert_eq!(context.used_gas.get(), SimpleContext::NEW_CELL_GAS * 5); // Equivalent to simple get
2267
2268        Ok(())
2269    }
2270}