Skip to main content

ic_storage/adapter/
iteration.rs

1//! Owned entries and iterator views over the copied ICSS engine.
2use super::{
3    Memory, Storable,
4    bridge::{Codec, TreeMemory},
5};
6use crate::{DefaultMemoryImpl, engine};
7use std::{borrow::Cow, marker::PhantomData};
8
9///
10/// `MapEntry`
11///
12/// An owned key and encoded value from an ordered scan. Decoding failures trap.
13///
14pub struct MapEntry<K, V> {
15    key: K,
16    bytes: Vec<u8>,
17    value: PhantomData<V>,
18}
19impl<K, V: Storable> MapEntry<K, V> {
20    /// Borrow the decoded key.
21    pub const fn key(&self) -> &K {
22        &self.key
23    }
24    /// Decode the value. Malformed stored bytes trap.
25    pub fn value(&self) -> V {
26        <Codec<V> as engine::Storable>::from_bytes(Cow::Borrowed(&self.bytes)).0
27    }
28    /// Consume the entry and decode its value.
29    pub fn into_pair(self) -> (K, V) {
30        (
31            self.key,
32            <Codec<V> as engine::Storable>::from_bytes(Cow::Owned(self.bytes)).0,
33        )
34    }
35    /// Consume only the key without decoding its value.
36    pub fn into_key(self) -> K {
37        self.key
38    }
39    /// Consume and decode only the value.
40    pub fn into_value(self) -> V {
41        <Codec<V> as engine::Storable>::from_bytes(Cow::Owned(self.bytes)).0
42    }
43}
44///
45/// `MapIter`
46///
47/// Bidirectional ICSS traversal retaining its governed map borrow.
48///
49pub struct MapIter<'a, K: Storable + Ord + Clone, V: Storable, M: Memory = DefaultMemoryImpl>(
50    pub(super) engine::btreemap::Iter<'a, Codec<K>, Codec<V>, TreeMemory<M>>,
51);
52fn entry<K: Storable + Ord + Clone, V: Storable, M: Memory>(
53    entry: engine::btreemap::LazyEntry<'_, Codec<K>, Codec<V>, TreeMemory<M>>,
54) -> MapEntry<K, V> {
55    let (key, bytes) = entry.into_raw();
56    MapEntry {
57        key: key.0,
58        bytes,
59        value: PhantomData,
60    }
61}
62impl<K: Storable + Ord + Clone, V: Storable, M: Memory> Iterator for MapIter<'_, K, V, M> {
63    type Item = MapEntry<K, V>;
64    fn next(&mut self) -> Option<Self::Item> {
65        self.0.next().map(entry)
66    }
67    fn nth(&mut self, n: usize) -> Option<Self::Item> {
68        self.0.nth(n).map(entry)
69    }
70    fn last(mut self) -> Option<Self::Item> {
71        // The reverse cursor already respects bounds and consumption from either end.
72        self.next_back()
73    }
74    fn count(self) -> usize {
75        self.0.count()
76    }
77    fn size_hint(&self) -> (usize, Option<usize>) {
78        self.0.size_hint()
79    }
80}
81impl<K: Storable + Ord + Clone, V: Storable, M: Memory> DoubleEndedIterator
82    for MapIter<'_, K, V, M>
83{
84    fn next_back(&mut self) -> Option<Self::Item> {
85        self.0.next_back().map(entry)
86    }
87    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
88        self.0.nth_back(n).map(entry)
89    }
90}