stdx/
iter.rs

1#[cfg(feature = "alloc")]
2use core::fmt;
3
4#[cfg(feature = "alloc")]
5use alloc::string::String;
6
7#[cfg(feature = "alloc")]
8use alloc::vec::Vec;
9
10pub trait IteratorExt: Iterator {
11    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
12    #[cfg(feature = "alloc")]
13    fn join_(&mut self, sep: &str) -> String
14    where
15        Self::Item: fmt::Display,
16    {
17        use core::fmt::Write as _;
18
19        match self.next() {
20            None => String::new(),
21            Some(first) => {
22                let (lower, _) = self.size_hint();
23                let mut buf = String::with_capacity(sep.len() * lower);
24                write!(&mut buf, "{first}").unwrap();
25                self.for_each(|item| {
26                    buf.push_str(sep);
27                    write!(&mut buf, "{item}").unwrap();
28                });
29                buf
30            }
31        }
32    }
33}
34
35impl<I: Iterator> IteratorExt for I {}
36
37pub fn map_collect<C, T, I, F>(iterable: I, f: F) -> C
38where
39    I: IntoIterator,
40    F: FnMut(I::Item) -> T,
41    C: FromIterator<T>,
42{
43    iterable.into_iter().map(f).collect()
44}
45
46#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
47#[cfg(feature = "alloc")]
48pub fn map_collect_vec<T, I, F>(iterable: I, f: F) -> Vec<T>
49where
50    I: IntoIterator,
51    F: FnMut(I::Item) -> T,
52{
53    map_collect(iterable, f)
54}
55
56pub fn filter_map_collect<C, T, I, F>(iterable: I, f: F) -> C
57where
58    I: IntoIterator,
59    F: FnMut(I::Item) -> Option<T>,
60    C: FromIterator<T>,
61{
62    iterable.into_iter().filter_map(f).collect()
63}
64
65#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
66#[cfg(feature = "alloc")]
67pub fn filter_map_collect_vec<T, I, F>(iterable: I, f: F) -> Vec<T>
68where
69    I: IntoIterator,
70    F: FnMut(I::Item) -> Option<T>,
71{
72    filter_map_collect(iterable, f)
73}