Skip to main content

ic_storage/adapter/
set.rs

1//! Governed set collection implementation.
2use super::error::{CollectionError as Error, Result, ensure};
3use super::{MapIter, Memory, StableBTreeMap, Storable};
4use crate::DefaultMemoryImpl;
5use crate::RuntimeMemory;
6
7/// Governed ordered set sharing Storage’s owned map engine with unit values.
8pub struct StableBTreeSet<K: Storable + Ord + Clone, M: Memory = DefaultMemoryImpl> {
9    inner: StableBTreeMap<K, (), M>,
10}
11impl<K: Storable + Ord + Clone, M: Memory> StableBTreeSet<K, M> {
12    /// Create a collection only in zero-page memory.
13    ///
14    /// # Errors
15    /// Refuses nonempty memory, invalid encoding or capacity exhaustion before writes.
16    pub fn create(memory: RuntimeMemory<M>) -> Result<Self> {
17        ensure(memory.size() == 0, Error::NotEmpty)?;
18        Self::reset(memory)
19    }
20
21    /// Deliberately replace any contents in this admitted allocation.
22    ///
23    /// # Errors
24    /// Returns encoding, capacity or structural admission errors.
25    pub fn reset(memory: RuntimeMemory<M>) -> Result<Self> {
26        Ok(Self {
27            inner: StableBTreeMap::reset(memory)?,
28        })
29    }
30
31    /// Load retained collection state without initializing a replacement.
32    ///
33    /// # Errors
34    /// Refuses empty, foreign or corrupt memory and incompatible bounds without writing.
35    pub fn load(memory: RuntimeMemory<M>) -> Result<Self> {
36        Ok(Self {
37            inner: StableBTreeMap::load(memory)?,
38        })
39    }
40    /// Perform `insert` on the governed ordered set.
41    ///
42    /// # Errors
43    /// Rejects encoding, decoding, structural or capacity errors before committing writes.
44    pub fn insert(&mut self, key: K) -> Result<bool> {
45        Ok(self.inner.insert(key, ())?.is_none())
46    }
47    /// Perform `contains` on the governed ordered set.
48    ///
49    /// # Errors
50    /// Reports structural, integrity or application decoding failures without writing.
51    pub fn contains(&self, key: &K) -> Result<bool> {
52        self.inner.contains_key(key)
53    }
54    /// Perform `is_empty` on the governed ordered set.
55    ///
56    /// # Errors
57    /// Reports invalid region metadata or incompatible codec bounds.
58    pub fn is_empty(&self) -> bool {
59        self.inner.is_empty()
60    }
61    /// Perform `len` on the governed ordered set.
62    pub fn len(&self) -> u64 {
63        self.inner.len()
64    }
65    /// Perform `remove` on the governed ordered set.
66    ///
67    /// # Errors
68    /// Rejects decoding or structural errors before committing removal.
69    pub fn remove(&mut self, key: &K) -> Result<bool> {
70        Ok(self.inner.remove(key)?.is_some())
71    }
72    /// Perform `iter` on the governed ordered set.
73    pub fn iter(&self) -> SetIter<'_, K, M> {
74        SetIter(self.inner.iter())
75    }
76}
77
78impl<'a, K: Storable + Ord + Clone, M: Memory> IntoIterator for &'a StableBTreeSet<K, M> {
79    type Item = Result<K>;
80    type IntoIter = SetIter<'a, K, M>;
81    fn into_iter(self) -> Self::IntoIter {
82        self.iter()
83    }
84}
85
86///
87/// `SetIter`
88///
89/// Lazy bidirectional key traversal over the shared ordered-tree engine.
90///
91pub struct SetIter<'a, K: Storable + Ord + Clone, M: Memory>(MapIter<'a, K, (), M>);
92impl<K: Storable + Ord + Clone, M: Memory> Iterator for SetIter<'_, K, M> {
93    type Item = Result<K>;
94    fn next(&mut self) -> Option<Result<K>> {
95        self.0
96            .next()
97            .map(|entry| entry.map(super::MapEntry::into_key))
98    }
99}
100impl<K: Storable + Ord + Clone, M: Memory> DoubleEndedIterator for SetIter<'_, K, M> {
101    fn next_back(&mut self) -> Option<Result<K>> {
102        self.0
103            .next_back()
104            .map(|entry| entry.map(super::MapEntry::into_key))
105    }
106}