1 unstable release
0.1.0 | Oct 24, 2024 |
---|
#735 in Rust patterns
115 downloads per month
14KB
214 lines
This crate provides a ShadowCountedIter
which counts every iteration to a hidden
counter. It is possible to create nested iterators, where their counter will be committed to a
parent iterator when reaching the end.
Unlike the std std::iter::Enumerate
iterator, the ShadowCountedIter
does not return the counter
to the user, instead it has to be queried with the counter()
and counter_rec()
methods.
We also provide a IntoShadowCounted
extension trait which converts any iterator into a
ShadowCountedIter
Examples
Basic Counting
use shadow_counted::{ShadowCountedIter, IntoShadowCounted};
let vec = vec![1, 2, 3];
let mut iter = vec.into_iter().shadow_counted();
while let Some(_) = iter.next() {}
assert_eq!(iter.counter(), 3);
Nested Counting
use shadow_counted::{ShadowCountedIter, IntoShadowCounted};
// Make a datastructure that may hold nested elements.
#[derive(Debug, PartialEq)]
enum Nodes<'a, T> {
Leaf(T),
Nested(&'a [Nodes<'a, T>]),
}
let items = &[
Nodes::Leaf(1),
Nodes::Nested(&[Nodes::Leaf(2), Nodes::Leaf(3)]),
Nodes::Leaf(4),
];
// iterate over the outer
let mut sc_iter = items.into_iter().shadow_counted();
assert_eq!(sc_iter.next(), Some(&Nodes::Leaf(1)));
// the 2nd element is nested data
let nested = sc_iter.next().unwrap();
# assert_eq!(nested, &Nodes::Nested(&[Nodes::Leaf(2), Nodes::Leaf(3)]));
let Nodes::Nested(nested) = nested else {unreachable!()};
// iterate over the nested elements, counting only leafs
let mut nested_iter = nested.into_iter().nested_shadow_counted(&sc_iter, true);
# assert_eq!(nested_iter.counter(), 0);
# assert_eq!(nested_iter.counter_rec(), 1);
assert_eq!(nested_iter.next(), Some(&Nodes::Leaf(2)));
# assert_eq!(nested_iter.counter(), 1);
# assert_eq!(nested_iter.counter_rec(), 2);
assert_eq!(nested_iter.next(), Some(&Nodes::Leaf(3)));
# assert_eq!(nested_iter.counter(), 2);
# assert_eq!(nested_iter.counter_rec(), 3);
# assert_eq!(sc_iter.counter(), 1);
// reaching the end commits to the parent iter
assert_eq!(nested_iter.next(), None);
assert_eq!(sc_iter.counter(), 3);
assert_eq!(nested_iter.counter(), 2);
# assert_eq!(nested_iter.counter_rec(), 3);
// back to the outer
assert_eq!(sc_iter.next(), Some(&Nodes::Leaf(4)));
# assert_eq!(sc_iter.counter(), 4);
# assert_eq!(sc_iter.next(), None);
assert_eq!(sc_iter.counter(), 4);
assert_eq!(sc_iter.counter_rec(), 4);