1use crate::{
4    blueprint::BlueprintInspect,
5    codec::{
6        Decode,
7        Encode,
8        Encoder,
9    },
10    kv_store::{
11        KVItem,
12        KeyItem,
13        KeyValueInspect,
14    },
15    structured_storage::TableWithBlueprint,
16    transactional::ReferenceBytesKey,
17};
18use fuel_vm_private::fuel_storage::Mappable;
19
20#[cfg(feature = "alloc")]
21use alloc::{
22    boxed::Box,
23    collections::BTreeMap,
24    vec::Vec,
25};
26
27pub mod changes_iterator;
28
29pub struct BoxedIter<'a, T> {
32    iter: Box<dyn Iterator<Item = T> + 'a + Send>,
33}
34
35impl<'a, T> Iterator for BoxedIter<'a, T> {
36    type Item = T;
37
38    fn next(&mut self) -> Option<Self::Item> {
39        self.iter.next()
40    }
41}
42
43pub trait IntoBoxedIter<'a, T> {
45    fn into_boxed(self) -> BoxedIter<'a, T>;
47}
48
49impl<'a, T, I> IntoBoxedIter<'a, T> for I
50where
51    I: Iterator<Item = T> + 'a + Send,
52{
53    fn into_boxed(self) -> BoxedIter<'a, T> {
54        BoxedIter {
55            iter: Box::new(self),
56        }
57    }
58}
59
60#[derive(Copy, Clone, Debug, PartialOrd, Eq, PartialEq)]
62pub enum IterDirection {
63    Forward,
65    Reverse,
67}
68
69impl Default for IterDirection {
70    fn default() -> Self {
71        Self::Forward
72    }
73}
74
75#[impl_tools::autoimpl(for<T: trait> &T, &mut T, Box<T>)]
77pub trait IterableStore: KeyValueInspect {
78    fn iter_store(
80        &self,
81        column: Self::Column,
82        prefix: Option<&[u8]>,
83        start: Option<&[u8]>,
84        direction: IterDirection,
85    ) -> BoxedIter<KVItem>;
86
87    fn iter_store_keys(
89        &self,
90        column: Self::Column,
91        prefix: Option<&[u8]>,
92        start: Option<&[u8]>,
93        direction: IterDirection,
94    ) -> BoxedIter<KeyItem>;
95}
96
97#[cfg(feature = "std")]
98impl<T> IterableStore for std::sync::Arc<T>
99where
100    T: IterableStore,
101{
102    fn iter_store(
103        &self,
104        column: Self::Column,
105        prefix: Option<&[u8]>,
106        start: Option<&[u8]>,
107        direction: IterDirection,
108    ) -> BoxedIter<KVItem> {
109        use core::ops::Deref;
110        self.deref().iter_store(column, prefix, start, direction)
111    }
112
113    fn iter_store_keys(
114        &self,
115        column: Self::Column,
116        prefix: Option<&[u8]>,
117        start: Option<&[u8]>,
118        direction: IterDirection,
119    ) -> BoxedIter<KeyItem> {
120        use core::ops::Deref;
121        self.deref()
122            .iter_store_keys(column, prefix, start, direction)
123    }
124}
125
126pub trait IterableTable<M>
128where
129    M: Mappable,
130{
131    fn iter_table_keys<P>(
133        &self,
134        prefix: Option<P>,
135        start: Option<&M::Key>,
136        direction: Option<IterDirection>,
137    ) -> BoxedIter<super::Result<M::OwnedKey>>
138    where
139        P: AsRef<[u8]>;
140
141    fn iter_table<P>(
143        &self,
144        prefix: Option<P>,
145        start: Option<&M::Key>,
146        direction: Option<IterDirection>,
147    ) -> BoxedIter<super::Result<(M::OwnedKey, M::OwnedValue)>>
148    where
149        P: AsRef<[u8]>;
150}
151
152impl<Column, M, S> IterableTable<M> for S
153where
154    M: TableWithBlueprint<Column = Column>,
155    M::Blueprint: BlueprintInspect<M, S>,
156    S: IterableStore<Column = Column>,
157{
158    fn iter_table_keys<P>(
159        &self,
160        prefix: Option<P>,
161        start: Option<&M::Key>,
162        direction: Option<IterDirection>,
163    ) -> BoxedIter<crate::Result<M::OwnedKey>>
164    where
165        P: AsRef<[u8]>,
166    {
167        let encoder = start.map(|start| {
168            <M::Blueprint as BlueprintInspect<M, Self>>::KeyCodec::encode(start)
169        });
170
171        let start = encoder.as_ref().map(|encoder| encoder.as_bytes());
172
173        IterableStore::iter_store_keys(
174            self,
175            M::column(),
176            prefix.as_ref().map(|p| p.as_ref()),
177            start.as_ref().map(|cow| cow.as_ref()),
178            direction.unwrap_or_default(),
179        )
180        .map(|res| {
181            res.and_then(|key| {
182                let key = <M::Blueprint as BlueprintInspect<M, Self>>::KeyCodec::decode(
183                    key.as_slice(),
184                )
185                .map_err(|e| crate::Error::Codec(anyhow::anyhow!(e)))?;
186                Ok(key)
187            })
188        })
189        .into_boxed()
190    }
191
192    fn iter_table<P>(
193        &self,
194        prefix: Option<P>,
195        start: Option<&M::Key>,
196        direction: Option<IterDirection>,
197    ) -> BoxedIter<super::Result<(M::OwnedKey, M::OwnedValue)>>
198    where
199        P: AsRef<[u8]>,
200    {
201        let encoder = start.map(|start| {
202            <M::Blueprint as BlueprintInspect<M, Self>>::KeyCodec::encode(start)
203        });
204
205        let start = encoder.as_ref().map(|encoder| encoder.as_bytes());
206
207        IterableStore::iter_store(
208            self,
209            M::column(),
210            prefix.as_ref().map(|p| p.as_ref()),
211            start.as_ref().map(|cow| cow.as_ref()),
212            direction.unwrap_or_default(),
213        )
214        .map(|val| {
215            val.and_then(|(key, value)| {
216                let key = <M::Blueprint as BlueprintInspect<M, Self>>::KeyCodec::decode(
217                    key.as_slice(),
218                )
219                .map_err(|e| crate::Error::Codec(anyhow::anyhow!(e)))?;
220                let value =
221                    <M::Blueprint as BlueprintInspect<M, Self>>::ValueCodec::decode(
222                        &value,
223                    )
224                    .map_err(|e| crate::Error::Codec(anyhow::anyhow!(e)))?;
225                Ok((key, value))
226            })
227        })
228        .into_boxed()
229    }
230}
231
232pub trait IteratorOverTable {
234    fn iter_all_keys<M>(
236        &self,
237        direction: Option<IterDirection>,
238    ) -> BoxedIter<super::Result<M::OwnedKey>>
239    where
240        M: Mappable,
241        Self: IterableTable<M>,
242    {
243        self.iter_all_filtered_keys::<M, [u8; 0]>(None, None, direction)
244    }
245
246    fn iter_all_by_prefix_keys<M, P>(
248        &self,
249        prefix: Option<P>,
250    ) -> BoxedIter<super::Result<M::OwnedKey>>
251    where
252        M: Mappable,
253        P: AsRef<[u8]>,
254        Self: IterableTable<M>,
255    {
256        self.iter_all_filtered_keys::<M, P>(prefix, None, None)
257    }
258
259    fn iter_all_by_start_keys<M>(
261        &self,
262        start: Option<&M::Key>,
263        direction: Option<IterDirection>,
264    ) -> BoxedIter<super::Result<M::OwnedKey>>
265    where
266        M: Mappable,
267        Self: IterableTable<M>,
268    {
269        self.iter_all_filtered_keys::<M, [u8; 0]>(None, start, direction)
270    }
271
272    fn iter_all_filtered_keys<M, P>(
274        &self,
275        prefix: Option<P>,
276        start: Option<&M::Key>,
277        direction: Option<IterDirection>,
278    ) -> BoxedIter<super::Result<M::OwnedKey>>
279    where
280        M: Mappable,
281        P: AsRef<[u8]>,
282        Self: IterableTable<M>,
283    {
284        self.iter_table_keys(prefix, start, direction)
285    }
286
287    fn iter_all<M>(
289        &self,
290        direction: Option<IterDirection>,
291    ) -> BoxedIter<super::Result<(M::OwnedKey, M::OwnedValue)>>
292    where
293        M: Mappable,
294        Self: IterableTable<M>,
295    {
296        self.iter_all_filtered::<M, [u8; 0]>(None, None, direction)
297    }
298
299    fn iter_all_by_prefix<M, P>(
301        &self,
302        prefix: Option<P>,
303    ) -> BoxedIter<super::Result<(M::OwnedKey, M::OwnedValue)>>
304    where
305        M: Mappable,
306        P: AsRef<[u8]>,
307        Self: IterableTable<M>,
308    {
309        self.iter_all_filtered::<M, P>(prefix, None, None)
310    }
311
312    fn iter_all_by_start<M>(
314        &self,
315        start: Option<&M::Key>,
316        direction: Option<IterDirection>,
317    ) -> BoxedIter<super::Result<(M::OwnedKey, M::OwnedValue)>>
318    where
319        M: Mappable,
320        Self: IterableTable<M>,
321    {
322        self.iter_all_filtered::<M, [u8; 0]>(None, start, direction)
323    }
324
325    fn iter_all_filtered<M, P>(
327        &self,
328        prefix: Option<P>,
329        start: Option<&M::Key>,
330        direction: Option<IterDirection>,
331    ) -> BoxedIter<super::Result<(M::OwnedKey, M::OwnedValue)>>
332    where
333        M: Mappable,
334        P: AsRef<[u8]>,
335        Self: IterableTable<M>,
336    {
337        self.iter_table(prefix, start, direction)
338    }
339}
340
341impl<S> IteratorOverTable for S {}
342
343pub fn iterator<'a, V>(
345    tree: &'a BTreeMap<ReferenceBytesKey, V>,
346    prefix: Option<&[u8]>,
347    start: Option<&[u8]>,
348    direction: IterDirection,
349) -> impl Iterator<Item = (&'a ReferenceBytesKey, &'a V)> + 'a
350where
351    V: Send + Sync,
352{
353    match (prefix, start) {
354        (None, None) => {
355            if direction == IterDirection::Forward {
356                tree.iter().into_boxed()
357            } else {
358                tree.iter().rev().into_boxed()
359            }
360        }
361        (Some(prefix), None) => {
362            let prefix = prefix.to_vec();
363            if direction == IterDirection::Forward {
364                tree.range(prefix.clone()..)
365                    .take_while(move |(key, _)| key.starts_with(prefix.as_slice()))
366                    .into_boxed()
367            } else {
368                let mut vec: Vec<_> = tree
369                    .range(prefix.clone()..)
370                    .into_boxed()
371                    .take_while(|(key, _)| key.starts_with(prefix.as_slice()))
372                    .collect();
373
374                vec.reverse();
375                vec.into_iter().into_boxed()
376            }
377        }
378        (None, Some(start)) => {
379            if direction == IterDirection::Forward {
380                tree.range(start.to_vec()..).into_boxed()
381            } else {
382                tree.range(..=start.to_vec()).rev().into_boxed()
383            }
384        }
385        (Some(prefix), Some(start)) => {
386            let prefix = prefix.to_vec();
387            if direction == IterDirection::Forward {
388                tree.range(start.to_vec()..)
389                    .take_while(move |(key, _)| key.starts_with(prefix.as_slice()))
390                    .into_boxed()
391            } else {
392                tree.range(..=start.to_vec())
393                    .rev()
394                    .take_while(move |(key, _)| key.starts_with(prefix.as_slice()))
395                    .into_boxed()
396            }
397        }
398    }
399}
400
401pub fn keys_iterator<'a, V>(
403    tree: &'a BTreeMap<ReferenceBytesKey, V>,
404    prefix: Option<&[u8]>,
405    start: Option<&[u8]>,
406    direction: IterDirection,
407) -> impl Iterator<Item = &'a ReferenceBytesKey> + 'a
408where
409    V: Send + Sync,
410{
411    match (prefix, start) {
412        (None, None) => {
413            if direction == IterDirection::Forward {
414                tree.keys().into_boxed()
415            } else {
416                tree.keys().rev().into_boxed()
417            }
418        }
419        (_, _) => iterator(tree, prefix, start, direction)
421            .map(|(key, _)| key)
422            .into_boxed(),
423    }
424}