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