ref_iter/sub/
iflat_map.rs

1//! Provider of [`IFlatMap`].
2
3use crate::closures::{FnIFlatMap, FnIFlatMapItem, FnIFlatMapIter};
4use crate::prelude::*;
5use crate::util::msg;
6use core::fmt::{self, Debug, Formatter};
7use core::mem;
8
9/// An iterator that flatten maped each dynamic borrowing iterators.
10///
11/// This struct is created by [`RefIterator::iflat_map`].
12#[must_use = msg::iter_must_use!()]
13pub struct IFlatMap<'this, I, F>
14where
15    I: RefIterator,
16    F: for<'x> FnIFlatMap<&'x I::Item>,
17{
18    /// Base iterator.
19    iter: I,
20    /// Sub iterator.
21    sub_iter: Option<FnIFlatMapIter<F, &'this I::Item>>,
22    /// Closure for each item mapping.
23    f: F,
24}
25
26impl<'this, I, F> IFlatMap<'this, I, F>
27where
28    I: RefIterator,
29    F: for<'x> FnIFlatMap<&'x I::Item>,
30{
31    /// Creates a new value.
32    pub(crate) fn new(iter: I, f: F) -> Self {
33        let sub_iter = None;
34        Self { iter, sub_iter, f }
35    }
36
37    /// Advance base iterator and returns next sub iterator.
38    fn next_sub_iter(&mut self) -> Option<FnIFlatMapIter<F, &'this I::Item>> {
39        let ret = (self.f)(self.iter.next()?).into_iter();
40        Some(unsafe { Self::adjust_sub_iter(ret) })
41    }
42
43    /// Adjust sub iterator lifetime.
44    unsafe fn adjust_sub_iter<'a>(
45        x: FnIFlatMapIter<F, &'_ I::Item>,
46    ) -> FnIFlatMapIter<F, &'a I::Item> {
47        #[rustfmt::skip]
48        return unsafe {
49            mem::transmute::<
50                FnIFlatMapIter<F, &'_ _>,
51                FnIFlatMapIter<F, &'a _>
52            >(x)
53        };
54    }
55}
56
57impl<'this, I, F> Clone for IFlatMap<'this, I, F>
58where
59    I: RefIterator + Clone,
60    F: for<'x> FnIFlatMap<&'x I::Item> + Clone,
61    FnIFlatMapIter<F, &'this I::Item>: Clone,
62{
63    fn clone(&self) -> Self {
64        Self {
65            iter: self.iter.clone(),
66            sub_iter: self.sub_iter.clone(),
67            f: self.f.clone(),
68        }
69    }
70}
71
72impl<'this, I, F> Debug for IFlatMap<'this, I, F>
73where
74    I: RefIterator + Debug,
75    F: for<'x> FnIFlatMap<&'x I::Item> + Debug,
76    FnIFlatMapIter<F, &'this I::Item>: Debug,
77{
78    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
79        f.debug_struct("RefFlatMap")
80            .field("iter", &self.iter)
81            .field("sub_iter", &self.sub_iter)
82            .field("f", &self.f)
83            .finish()
84    }
85}
86
87impl<'this, I, F> Iterator for IFlatMap<'this, I, F>
88where
89    I: RefIterator,
90    F: for<'x> FnIFlatMap<&'x I::Item>,
91{
92    type Item = FnIFlatMapItem<F, &'this I::Item>;
93
94    fn next(&mut self) -> Option<Self::Item> {
95        if self.sub_iter.is_none() {
96            self.sub_iter = self.next_sub_iter();
97        }
98
99        loop {
100            let item = self.sub_iter.as_mut().unwrap().next();
101            if item.is_some() {
102                return item;
103            }
104
105            self.sub_iter = Some(self.next_sub_iter()?);
106        }
107    }
108}