rune_alloc/iter/
try_from_iterator.rs

1use crate::alloc::{Allocator, Global};
2use crate::error::Error;
3
4/// Conversion from an [`Iterator`] within a custom allocator `A`.
5///
6/// By implementing `TryFromIteratorIn` for a type, you define how it will be
7/// created from an iterator. This is common for types which describe a
8/// collection of some kind.
9pub trait TryFromIteratorIn<T, A: Allocator>: Sized {
10    /// Creates a value from an iterator within an allocator.
11    fn try_from_iter_in<I>(iter: I, alloc: A) -> Result<Self, Error>
12    where
13        I: IntoIterator<Item = T>;
14}
15
16/// Conversion from an [`Iterator`] within the [`Global`] allocator.
17///
18/// By implementing `TryFromIteratorIn` for a type, you define how it will be created
19/// from an iterator. This is common for types which describe a collection of
20/// some kind.
21pub trait TryFromIterator<T>: TryFromIteratorIn<T, Global> {
22    /// Creates a value from an iterator within an allocator.
23    fn try_from_iter<I>(iter: I) -> Result<Self, Error>
24    where
25        I: IntoIterator<Item = T>;
26}
27
28impl<T, U> TryFromIterator<T> for U
29where
30    U: TryFromIteratorIn<T, Global>,
31{
32    #[inline]
33    fn try_from_iter<I>(iter: I) -> Result<Self, Error>
34    where
35        I: IntoIterator<Item = T>,
36    {
37        U::try_from_iter_in(iter, Global)
38    }
39}
40
41impl<T, U, E, A: Allocator> TryFromIteratorIn<Result<T, E>, A> for Result<U, E>
42where
43    U: TryFromIteratorIn<T, A>,
44{
45    fn try_from_iter_in<I>(iter: I, alloc: A) -> Result<Self, Error>
46    where
47        I: IntoIterator<Item = Result<T, E>>,
48    {
49        struct Iter<'a, I, E> {
50            error: &'a mut Option<E>,
51            iter: I,
52        }
53
54        impl<T, I, E> Iterator for Iter<'_, I, E>
55        where
56            I: Iterator<Item = Result<T, E>>,
57        {
58            type Item = T;
59
60            fn next(&mut self) -> Option<Self::Item> {
61                let value = match self.iter.next()? {
62                    Ok(value) => value,
63                    Err(error) => {
64                        *self.error = Some(error);
65                        return None;
66                    }
67                };
68
69                Some(value)
70            }
71        }
72
73        let mut error = None;
74
75        let iter = Iter {
76            error: &mut error,
77            iter: iter.into_iter(),
78        };
79
80        let out = U::try_from_iter_in(iter, alloc)?;
81
82        match error {
83            Some(error) => Ok(Err(error)),
84            None => Ok(Ok(out)),
85        }
86    }
87}