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}