| Crates.io | shadow_counted |
| lib.rs | shadow_counted |
| version | 0.7.0 |
| created_at | 2024-10-24 12:52:13.581095+00 |
| updated_at | 2025-10-29 04:42:35.680221+00 |
| description | An iterator that counts every iteration in a hidden counter, nested iterators may commit the count to parents |
| homepage | |
| repository | https://seed.pipapo.org/nodes/seed.pipapo.org/rad:zuUvsqfRdsC1NraTegYHBMtCmm2Z |
| max_upload_size | |
| id | 1421302 |
| size | 263,365 |
This crate provides a [ShadowCountedIter] which counts every iteration to a hidden
counter. It is possible to create nested iterators which can commit their counter to their parent
iterator. Additionally, iterators can carry supplemental data through the iteration process.
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 [ShadowCountedIter::counter()] method.
We also provide a [IntoShadowCounted] extension trait which converts any iterator into a
[ShadowCountedIter].
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);
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 `Node::Nested(..)'
let element = sc_iter.next().unwrap();
# assert_eq!(element, &Nodes::Nested(&[Nodes::Leaf(2), Nodes::Leaf(3)]));
// since we dont want to count `Nested` we substract one from the counter
sc_iter.add(-1);
let Nodes::Nested(nested) = element else {unreachable!()};
let mut nested_iter = nested.into_iter().nested_shadow_counted(&mut sc_iter);
# assert_eq!(nested_iter.counter(), 1);
assert_eq!(nested_iter.next(), Some(&Nodes::Leaf(2)));
# assert_eq!(nested_iter.counter(), 2);
assert_eq!(nested_iter.next(), Some(&Nodes::Leaf(3)));
# assert_eq!(nested_iter.counter(), 3);
// reaching the end, commit to the parent iter
assert_eq!(nested_iter.next(), None);
// eventually a nested iter must be committed when its progress should be counted
nested_iter.commit();
// back to the outer
assert_eq!(sc_iter.counter(), 3);
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);
You can attach supplemental data to iterators that gets cloned when nesting and can be
committed back to the parent. The parent data must use interior mutability (like Cell)
to allow updates during commit:
use shadow_counted::{Commit, ShadowCountedIter, IntoShadowCounted};
use std::cell::Cell;
#[derive(Clone, Default, Debug)]
struct Stats {
count: Cell<u32>,
}
impl Commit for Stats {
fn commit(&self, from: Self) {
self.count.set(self.count.get() + from.count.get());
}
}
let mut parent = ShadowCountedIter::new_with(
vec![1, 2].into_iter(),
Stats::default()
);
let mut nested = vec![3, 4].into_iter().nested_shadow_counted(&mut parent);
nested.supplement_mut().count.set(5);
nested.commit().unwrap();
// Stats were committed from nested to parent
assert_eq!(parent.supplement().count.get(), 5);
shadow_counted is distributed via radicle its identifier is rad:zuUvsqfRdsC1NraTegYHBMtCmm2Z
You can clone the repository using git by:
git clone https://seed.pipapo.org/zuUvsqfRdsC1NraTegYHBMtCmm2Z.git shadow_counted
When you spot a problem or need a new feature feel free to open an issue or (prefered!) send a PR.
Commits and other git operations are augmented and validated with
bar. For
contributors it is recommened to enable bar too by calling ./bar activate
within a checked out unsynn repository.
Chances to get contributions merged increase when you:
./bar lints is a absolute requirement, I am not even looking at contributions
that fail basic lint and formatting checks. Hint: try ./bar dwim to apply formatting and
trivial fixes../bar without errors or warnings. Although if some problems and errors
remain to be discussed then a WIP-PR failing tests is temporary acceptable../bar cargo_mutants.