rune_alloc/iter/
ext.rs

1use crate::alloc::{Allocator, Global};
2use crate::clone::TryClone;
3use crate::error::Error;
4use crate::iter::{TryCloned, TryFromIteratorIn, TryJoin};
5
6/// Iterator extension trait.
7pub trait IteratorExt
8where
9    Self: Iterator + self::sealed::Sealed,
10{
11    /// Transforms an iterator into a collection using fallible allocations.
12    fn try_collect<B>(self) -> Result<B, Error>
13    where
14        Self: Sized,
15        B: TryFromIteratorIn<Self::Item, Global>,
16    {
17        self.try_collect_in(Global)
18    }
19
20    /// Transforms an iterator into a collection using fallible allocations.
21    fn try_collect_in<B, A>(self, alloc: A) -> Result<B, Error>
22    where
23        Self: Sized,
24        B: TryFromIteratorIn<Self::Item, A>,
25        A: Allocator,
26    {
27        TryFromIteratorIn::try_from_iter_in(self, alloc)
28    }
29
30    /// Try to join the given value.
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// use rune::alloc::String;
36    /// use rune::alloc::prelude::*;
37    ///
38    /// let values = ["foo", "bar"];
39    /// let string: String = values.into_iter().try_join("/")?;
40    /// assert_eq!(string, "foo/bar");
41    ///
42    /// let values = ["foo", "bar"];
43    /// let string: String = values.into_iter().try_join('/')?;
44    /// assert_eq!(string, "foo/bar");
45    /// # Ok::<_, rune::alloc::Error>(())
46    /// ```
47    fn try_join<J, S>(self, sep: S) -> Result<J, Error>
48    where
49        Self: Sized,
50        J: TryJoin<S, Self::Item, Global>,
51    {
52        J::try_join_in(self, sep, Global)
53    }
54
55    /// Try to join the given value.
56    fn try_join_in<J, S, A>(self, sep: S, alloc: A) -> Result<J, Error>
57    where
58        Self: Sized,
59        J: TryJoin<S, Self::Item, A>,
60        A: Allocator,
61    {
62        J::try_join_in(self, sep, alloc)
63    }
64
65    /// Creates an iterator which [`try_clone`]s all of its elements.
66    ///
67    /// This is useful when you have an iterator over `&T`, but you need an
68    /// iterator over `T`.
69    ///
70    /// There is no guarantee whatsoever about the `try_clone` method actually
71    /// being called *or* optimized away. So code should not depend on either.
72    ///
73    /// [`try_clone`]: TryClone::try_clone
74    ///
75    /// # Examples
76    ///
77    /// Basic usage:
78    ///
79    /// ```
80    /// use rune::alloc::{try_vec, Vec};
81    /// use rune::alloc::prelude::*;
82    ///
83    /// let a = [1, 2, 3];
84    ///
85    /// let v_cloned: Vec<_> = a.iter().try_cloned().try_collect::<Result<_, _>>()??;
86    ///
87    /// // cloned is the same as .map(|&x| x), for integers
88    /// let v_map: Vec<_> = a.iter().map(|&x| x).try_collect()?;
89    ///
90    /// assert_eq!(v_cloned, [1, 2, 3]);
91    /// assert_eq!(v_map, [1, 2, 3]);
92    /// # Ok::<_, rune::alloc::Error>(())
93    /// ```
94    fn try_cloned<'a, T>(self) -> TryCloned<Self>
95    where
96        Self: Sized + Iterator<Item = &'a T>,
97        T: 'a + TryClone,
98    {
99        TryCloned::new(self)
100    }
101}
102
103impl<I> IteratorExt for I where I: Iterator {}
104
105mod sealed {
106    pub trait Sealed {}
107    impl<I> Sealed for I where I: Iterator {}
108}