shadow_counted 0.7.0

An iterator that counts every iteration in a hidden counter, nested iterators may commit the count to parents
Documentation
use shadow_counted::IntoShadowCounted;

/// Test extremely large counter values
#[test]
fn test_large_counter_values() {
    let mut iter = vec![1].into_iter().shadow_counted();

    // Add a very large value
    iter.add(isize::MAX - 100);
    assert_eq!(iter.counter(), (isize::MAX - 100) as usize);

    iter.next();
    assert_eq!(iter.counter(), (isize::MAX - 99) as usize);
}

/// Test iterator with many items
#[test]
fn test_many_items() {
    let data: Vec<i32> = (0..10000).collect();
    let mut iter = data.into_iter().shadow_counted();

    for _ in iter.by_ref() {}
    assert_eq!(iter.counter(), 10000);
}

/// Test deeply nested hierarchy
#[test]
fn test_very_deep_nesting() {
    let mut level0 = vec![0].into_iter().shadow_counted();
    level0.next();

    let mut level1 = vec![1].into_iter().nested_shadow_counted(&mut level0);
    level1.next();

    let mut level2 = vec![2].into_iter().nested_shadow_counted(&mut level1);
    level2.next();

    let mut level3 = vec![3].into_iter().nested_shadow_counted(&mut level2);
    level3.next();

    let mut level4 = vec![4].into_iter().nested_shadow_counted(&mut level3);
    level4.next();

    level4.commit().unwrap();
    level3.commit().unwrap();
    level2.commit().unwrap();
    level1.commit().unwrap();

    assert_eq!(level0.counter(), 5);
}

/// Test cloning preserves counter state
#[test]
fn test_clone_preserves_state() {
    let mut iter1 = vec![1, 2, 3, 4, 5].into_iter().shadow_counted();
    iter1.next();
    iter1.next();

    let iter2 = iter1.clone();

    assert_eq!(iter1.counter(), iter2.counter());
}

/// Test cloned iterators increment independently
#[test]
fn test_cloned_iterators_independent() {
    let mut iter1 = vec![1, 2, 3].into_iter().shadow_counted();
    iter1.next();

    let mut iter2 = iter1.clone();

    iter1.next();
    assert_eq!(iter1.counter(), 2);
    assert_eq!(iter2.counter(), 1); // Independent

    iter2.next();
    iter2.next();
    assert_eq!(iter2.counter(), 3);
    assert_eq!(iter1.counter(), 2); // Unchanged
}

/// Test iterator with ZST (Zero-Sized Type)
#[test]
fn test_zst_iterator() {
    let data = vec![(), (), ()];
    let mut iter = data.into_iter().shadow_counted();

    for _ in iter.by_ref() {}
    assert_eq!(iter.counter(), 3);
}

/// Test that counter is correct after partial consumption
#[test]
fn test_partial_consumption() {
    let data = vec![1, 2, 3, 4, 5];
    let mut iter = data.into_iter().shadow_counted();

    iter.next();
    iter.next();
    assert_eq!(iter.counter(), 2);

    // Don't consume the rest
    drop(iter);
}

/// Test add with zero
#[test]
fn test_add_zero() {
    let mut iter = vec![1, 2].into_iter().shadow_counted();

    iter.add(0);
    assert_eq!(iter.counter(), 0);

    iter.next();
    assert_eq!(iter.counter(), 1);
}

/// Test nesting empty into non-empty
#[test]
fn test_nest_empty_into_nonempty() {
    let mut parent = vec![1, 2, 3, 4, 5].into_iter().shadow_counted();
    parent.next();
    parent.next();

    let empty: Vec<i32> = vec![];
    let mut nested = empty.into_iter().nested_shadow_counted(&mut parent);

    assert_eq!(nested.counter(), 2);
    assert!(nested.next().is_none());
    assert_eq!(nested.counter(), 2);

    nested.commit().unwrap();
    assert_eq!(parent.counter(), 2);
}

/// Test nesting non-empty into empty
#[test]
fn test_nest_nonempty_into_empty() {
    let empty: Vec<i32> = vec![];
    let mut parent = empty.into_iter().shadow_counted();

    let mut nested = vec![1, 2, 3].into_iter().nested_shadow_counted(&mut parent);

    for _ in nested.by_ref() {}
    assert_eq!(nested.counter(), 3);

    nested.commit().unwrap();
    assert_eq!(parent.counter(), 3);
}

/// Test multiple add() calls
#[test]
fn test_multiple_adds() {
    let mut iter = vec![1].into_iter().shadow_counted();

    iter.add(5);
    iter.add(3);
    iter.add(2);

    assert_eq!(iter.counter(), 10);

    iter.next();
    assert_eq!(iter.counter(), 11);
}

/// Test that counter survives through various iterator adapters
#[test]
fn test_counter_with_iterator_adapters() {
    let data = vec![1, 2, 3, 4, 5];
    let mut iter = data.into_iter().shadow_counted();

    // Use some iterator adapters
    iter.by_ref().take(3).for_each(|_| {});

    assert_eq!(iter.counter(), 3);

    // Continue iteration
    iter.next();
    assert_eq!(iter.counter(), 4);
}