Skip to main content

soroban_sdk/
iter.rs

1//! Iterators for use with collections like [Map], [Vec].
2//!
3//! Collections are not guaranteed to contain values of the expected type as
4//! they are stored on the host as [Val]s, so two iterators are provided:
5//!
6//! - **`try_iter()`** returns an iterator that yields `Result<T, E>` for each
7//!   element, allowing the caller to handle conversion errors.
8//! - **`iter()`** returns an iterator that unwraps each result,
9//!   panicking if any element cannot be converted to the declared type.
10#[cfg(doc)]
11use crate::{Map, Val, Vec};
12
13use core::fmt::Debug;
14use core::iter::FusedIterator;
15use core::marker::PhantomData;
16
17pub trait UnwrappedEnumerable<I, T, E> {
18    fn unwrapped(self) -> UnwrappedIter<I, T, E>;
19}
20
21impl<I, T, E> UnwrappedEnumerable<I, T, E> for I
22where
23    I: Iterator<Item = Result<T, E>>,
24    E: Debug,
25{
26    fn unwrapped(self) -> UnwrappedIter<I, T, E> {
27        UnwrappedIter {
28            iter: self,
29            item_type: PhantomData,
30            error_type: PhantomData,
31        }
32    }
33}
34
35#[derive(Clone)]
36pub struct UnwrappedIter<I, T, E> {
37    iter: I,
38    item_type: PhantomData<T>,
39    error_type: PhantomData<E>,
40}
41
42impl<I, T, E> Iterator for UnwrappedIter<I, T, E>
43where
44    I: Iterator<Item = Result<T, E>>,
45    E: Debug,
46{
47    type Item = T;
48
49    #[inline(always)]
50    fn next(&mut self) -> Option<Self::Item> {
51        self.iter.next().map(Result::unwrap)
52    }
53
54    #[inline(always)]
55    fn size_hint(&self) -> (usize, Option<usize>) {
56        self.iter.size_hint()
57    }
58}
59
60impl<I, T, E> DoubleEndedIterator for UnwrappedIter<I, T, E>
61where
62    I: Iterator<Item = Result<T, E>> + DoubleEndedIterator,
63    E: Debug,
64{
65    #[inline(always)]
66    fn next_back(&mut self) -> Option<Self::Item> {
67        self.iter.next_back().map(Result::unwrap)
68    }
69}
70
71impl<I, T, E> FusedIterator for UnwrappedIter<I, T, E>
72where
73    I: Iterator<Item = Result<T, E>> + FusedIterator,
74    E: Debug,
75{
76}
77
78impl<I, T, E> ExactSizeIterator for UnwrappedIter<I, T, E>
79where
80    I: Iterator<Item = Result<T, E>> + ExactSizeIterator,
81    E: Debug,
82{
83    #[inline(always)]
84    fn len(&self) -> usize {
85        self.iter.len()
86    }
87}