pub mod clone_ext;
pub mod config;
pub mod config_value;
pub mod content;
pub mod context;
pub mod error;
pub mod filename;
mod filter;
mod front_matter;
#[cfg(feature = "renderer")]
pub mod highlight;
pub mod html;
#[cfg(feature = "renderer")]
pub mod html2md;
pub mod html_renderer;
#[cfg(feature = "lang-detection")]
pub mod lingua;
pub mod markup_language;
mod note;
pub mod settings;
pub mod template;
pub mod text_reader;
pub mod workflow;
use std::iter::FusedIterator;
pub struct FlattenWithIndex<I>
where
I: Iterator,
I::Item: IntoIterator,
{
iter: I,
current_inner: Option<<I::Item as IntoIterator>::IntoIter>,
outer_index: usize, }
impl<I> FlattenWithIndex<I>
where
I: Iterator,
I::Item: IntoIterator,
{
pub fn new(iter: I) -> Self {
Self {
iter,
current_inner: None,
outer_index: 0,
}
}
}
impl<I> Iterator for FlattenWithIndex<I>
where
I: Iterator,
I::Item: IntoIterator,
{
type Item = (usize, <I::Item as IntoIterator>::Item);
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(inner) = &mut self.current_inner {
if let Some(item) = inner.next() {
return Some((self.outer_index - 1, item)); }
}
let next_outer = self.iter.next()?;
self.current_inner = Some(next_outer.into_iter());
self.outer_index += 1;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (inner_lower, inner_upper) = self
.current_inner
.as_ref()
.map_or((0, None), |inner| inner.size_hint());
let (outer_lower, outer_upper) = self.iter.size_hint();
let lower = inner_lower.saturating_add(outer_lower);
let upper = match (inner_upper, outer_upper) {
(Some(i), Some(o)) => i.checked_add(o),
_ => None,
};
(lower, upper)
}
}
impl<I> FusedIterator for FlattenWithIndex<I>
where
I: Iterator + FusedIterator,
I::Item: IntoIterator,
<I::Item as IntoIterator>::IntoIter: FusedIterator,
{
}
pub trait FlattenWithIndexExt: Iterator {
fn flatten_with_index(self) -> FlattenWithIndex<Self>
where
Self::Item: IntoIterator,
Self: Sized,
{
FlattenWithIndex::new(self)
}
}
impl<T: Iterator> FlattenWithIndexExt for T {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_flatten_with_index() {
let data = vec![vec!['a', 'b'], vec!['c', 'd'], vec!['e', 'f', 'g']];
let result: Vec<(usize, char)> = data.into_iter().flatten_with_index().collect();
let expected = vec![
(0, 'a'),
(0, 'b'),
(1, 'c'),
(1, 'd'),
(2, 'e'),
(2, 'f'),
(2, 'g'),
];
assert_eq!(result, expected);
let data: Vec<Vec<char>> = Vec::new();
let result: Vec<(usize, char)> = data.into_iter().flatten_with_index().collect();
assert!(result.is_empty());
let data = vec![
vec!['a', 'b'],
vec![], vec!['c', 'd'],
];
let result: Vec<(usize, char)> = data.into_iter().flatten_with_index().collect();
let expected = vec![(0, 'a'), (0, 'b'), (2, 'c'), (2, 'd')];
assert_eq!(result, expected);
let data = vec![
vec!['a', 'b'],
vec![], vec!['c'],
vec![], vec!['d', 'e', 'f'],
];
let result: Vec<(usize, char)> = data.into_iter().flatten_with_index().collect();
let expected = vec![(0, 'a'), (0, 'b'), (2, 'c'), (4, 'd'), (4, 'e'), (4, 'f')];
assert_eq!(result, expected);
let data = vec![vec![], vec![], vec![]];
let result: Vec<(usize, char)> = data.into_iter().flatten_with_index().collect();
assert!(result.is_empty());
let data = vec![vec!['a', 'b', 'c']];
let result: Vec<(usize, char)> = data.into_iter().flatten_with_index().collect();
let expected = vec![(0, 'a'), (0, 'b'), (0, 'c')];
assert_eq!(result, expected);
let data = vec![
vec!['a'], vec!['b', 'c'], vec!['d'], ];
let result: Vec<(usize, char)> = data.into_iter().flatten_with_index().collect();
let expected = vec![(0, 'a'), (1, 'b'), (1, 'c'), (2, 'd')];
assert_eq!(result, expected);
}
}