use crate::Line;
type Inner<'b> = std::iter::Map<
std::slice::Iter<'b, Line>, for<'a> fn(&'a Line) -> &'a str
>;
type TaggedInner<'b> = std::iter::Map<
std::slice::Iter<'b, Line>, for<'a> fn(&'a Line) -> (char, &'a str)
>;
pub struct LinesIter<'a> {
inner: LinesIterInner<'a>,
}
enum LinesIterInner<'a> {
Real(Inner<'a>),
#[cfg(any(feature = "testing", fuzzing, test))]
Test(Box<dyn Iterator<Item = &'a str>>),
}
impl<'a> Iterator for LinesIter<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
match &mut self.inner {
LinesIterInner::Real(x) => x.next(),
#[cfg(any(feature = "testing", fuzzing, test))]
LinesIterInner::Test(x) => x.next(),
}
}
}
impl<'a> From<Inner<'a>> for LinesIter<'a> {
fn from(i: Inner<'a>) -> Self {
Self{ inner: LinesIterInner::Real(i) }
}
}
#[cfg(any(feature = "testing", fuzzing, test))]
impl<'a, I: Iterator<Item=&'a str> + 'static> From<Box<I>> for LinesIter<'a> {
fn from(i: Box<I>) -> Self {
Self{ inner: LinesIterInner::Test(i) }
}
}
pub struct TaggedLinesIter<'a> {
inner: TaggedInner<'a>,
}
impl<'a> Iterator for TaggedLinesIter<'a> {
type Item = (char, &'a str);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<'a> From<TaggedInner<'a>> for TaggedLinesIter<'a> {
fn from(i: TaggedInner<'a>) -> Self {
Self{ inner: i }
}
}