use crate::closures::{FnIFlatMap, FnIFlatMapItem, FnIFlatMapIter};
use crate::prelude::*;
use crate::util::msg;
use core::fmt::{self, Debug, Formatter};
use core::mem;
#[must_use = msg::iter_must_use!()]
pub struct IFlatMap<'this, I, F>
where
I: RefIterator,
F: for<'x> FnIFlatMap<&'x I::Item>,
{
iter: I,
sub_iter: Option<FnIFlatMapIter<F, &'this I::Item>>,
f: F,
}
impl<'this, I, F> IFlatMap<'this, I, F>
where
I: RefIterator,
F: for<'x> FnIFlatMap<&'x I::Item>,
{
pub(crate) fn new(iter: I, f: F) -> Self {
let sub_iter = None;
Self { iter, sub_iter, f }
}
fn next_sub_iter(&mut self) -> Option<FnIFlatMapIter<F, &'this I::Item>> {
let ret = (self.f)(self.iter.next()?).into_iter();
Some(unsafe { Self::adjust_sub_iter(ret) })
}
unsafe fn adjust_sub_iter<'a>(
x: FnIFlatMapIter<F, &'_ I::Item>,
) -> FnIFlatMapIter<F, &'a I::Item> {
#[rustfmt::skip]
return unsafe {
mem::transmute::<
FnIFlatMapIter<F, &'_ _>,
FnIFlatMapIter<F, &'a _>
>(x)
};
}
}
impl<'this, I, F> Clone for IFlatMap<'this, I, F>
where
I: RefIterator + Clone,
F: for<'x> FnIFlatMap<&'x I::Item> + Clone,
FnIFlatMapIter<F, &'this I::Item>: Clone,
{
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
sub_iter: self.sub_iter.clone(),
f: self.f.clone(),
}
}
}
impl<'this, I, F> Debug for IFlatMap<'this, I, F>
where
I: RefIterator + Debug,
F: for<'x> FnIFlatMap<&'x I::Item> + Debug,
FnIFlatMapIter<F, &'this I::Item>: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("RefFlatMap")
.field("iter", &self.iter)
.field("sub_iter", &self.sub_iter)
.field("f", &self.f)
.finish()
}
}
impl<'this, I, F> Iterator for IFlatMap<'this, I, F>
where
I: RefIterator,
F: for<'x> FnIFlatMap<&'x I::Item>,
{
type Item = FnIFlatMapItem<F, &'this I::Item>;
fn next(&mut self) -> Option<Self::Item> {
if self.sub_iter.is_none() {
self.sub_iter = self.next_sub_iter();
}
loop {
let item = self.sub_iter.as_mut().unwrap().next();
if item.is_some() {
return item;
}
self.sub_iter = Some(self.next_sub_iter()?);
}
}
}