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}