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}