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 simple nesting
#[test]
fn test_simple_nesting() {
    let mut parent = vec![1, 2, 3].into_iter().shadow_counted();
    parent.next();
    assert_eq!(parent.counter(), 1);

    let mut nested = vec![10, 20].into_iter().nested_shadow_counted(&mut parent);
    assert_eq!(nested.counter(), 1); // Inherits parent count
    nested.next();
    assert_eq!(nested.counter(), 2);
    nested.next();
    assert_eq!(nested.counter(), 3);

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

/// Test nested iterator doesn't affect parent until commit
#[test]
fn test_nested_isolation_before_commit() {
    let mut parent = vec![1, 2, 3].into_iter().shadow_counted();
    parent.next();
    assert_eq!(parent.counter(), 1);

    let mut nested = vec![10, 20, 30]
        .into_iter()
        .nested_shadow_counted(&mut parent);
    nested.next();
    nested.next();
    nested.next();
    assert_eq!(nested.counter(), 4);

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

/// Test deep nesting (3 levels)
#[test]
fn test_deep_nesting() {
    let mut level1 = vec![1].into_iter().shadow_counted();
    level1.next();
    assert_eq!(level1.counter(), 1);

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

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

    level3.commit().unwrap();
    assert_eq!(level2.counter(), 3);

    level2.commit().unwrap();
    assert_eq!(level1.counter(), 3);
}

/// Test multiple sequential nested iterators
#[test]
fn test_multiple_sequential_nesting() {
    let mut parent = vec![1, 2, 3].into_iter().shadow_counted();
    parent.next();
    assert_eq!(parent.counter(), 1);

    // First nested
    let mut nested1 = vec![10].into_iter().nested_shadow_counted(&mut parent);
    nested1.next();
    nested1.commit().unwrap();
    assert_eq!(parent.counter(), 2);

    parent.next();
    assert_eq!(parent.counter(), 3);

    // Second nested
    let mut nested2 = vec![20, 21].into_iter().nested_shadow_counted(&mut parent);
    nested2.next();
    nested2.next();
    nested2.commit().unwrap();
    assert_eq!(parent.counter(), 5);
}

/// Test nesting with empty iterators
#[test]
fn test_nesting_with_empty() {
    let mut parent = vec![1, 2].into_iter().shadow_counted();
    parent.next();

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

    assert_eq!(parent.counter(), 1); // Unchanged
}

/// Test commit without consuming nested iterator
#[test]
fn test_commit_without_consuming() {
    let mut parent = vec![1].into_iter().shadow_counted();
    parent.next();

    let nested = vec![10, 20].into_iter().nested_shadow_counted(&mut parent);
    // Don't consume, just commit
    nested.commit().unwrap();

    assert_eq!(parent.counter(), 1);
}

/// Test that parent can continue after nested commit
#[test]
fn test_parent_continues_after_nested() {
    let mut parent = vec![1, 2, 3, 4, 5].into_iter().shadow_counted();
    parent.next();
    parent.next();

    let mut nested = vec![10].into_iter().nested_shadow_counted(&mut parent);
    nested.next();
    nested.commit().unwrap();

    // Parent can continue
    parent.next();
    parent.next();
    assert_eq!(parent.counter(), 5);
}