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