shadow_counted/lib.rs
1#![doc = include_str!("../README.md")]
2
3use std::cell::Cell;
4
5/// Trait for types that can be committed from a child to a parent during nesting.
6///
7/// When a nested iterator commits, this trait controls how the supplemental data
8/// flows from the child to the parent. The default implementations for `()`, `Rc<T>`,
9/// and `Arc<T>` are no-ops, meaning the data doesn't propagate back.
10///
11/// The parent is immutable (`&self`) and the child is consumed by value. The implementor
12/// must use interior mutability (e.g., `Cell`, `RefCell`) if they need to mutate the parent.
13///
14/// # Examples
15///
16/// ```
17/// use shadow_counted::Commit;
18/// use std::cell::Cell;
19///
20/// #[derive(Clone, Default)]
21/// struct Counter {
22/// count: Cell<u32>,
23/// }
24///
25/// impl Commit for Counter {
26/// fn commit(&self, from: Self) {
27/// self.count.set(self.count.get() + from.count.get());
28/// }
29/// }
30/// ```
31pub trait Commit {
32 /// Called when a nested iterator commits to its parent.
33 /// The implementation should merge/update the parent's state using interior mutability.
34 ///
35 /// # Arguments
36 ///
37 /// * `from` - The child's supplemental data (consumed by value)
38 fn commit(&self, from: Self);
39}
40
41// No-op implementation for unit type (default)
42impl Commit for () {
43 fn commit(&self, _from: Self) {}
44}
45
46// No-op implementation for Rc (sharing via clone is sufficient)
47impl<T> Commit for std::rc::Rc<T> {
48 fn commit(&self, _from: Self) {}
49}
50
51// No-op implementation for Arc (sharing via clone is sufficient)
52impl<T> Commit for std::sync::Arc<T> {
53 fn commit(&self, _from: Self) {}
54}
55
56/// An iterator that counts every iteration and optionally commits the count to a parent iterator.
57/// Can carry supplemental data of type S through the iteration process.
58///
59/// Note that the `ShadowCountedIter` implements methods on its own. These can only be accessed
60/// while having the iterator itself available. Thus using a `for` loop is often not possible,
61/// instead a `while let Some(item) = iterator.next() {...}` loop is required to iterate over
62/// its elements.
63#[derive(Debug, Clone)]
64pub struct ShadowCountedIter<'a, I: Iterator, S = ()> {
65 iter: I,
66 counter: ShadowCounter<'a, S>,
67}
68
69impl<'a, I: Iterator, S: Default> ShadowCountedIter<'a, I, S> {
70 /// Creates a new ShadowCountedIter from an iterator.
71 ///
72 /// # Example
73 ///
74 /// ```
75 /// # use shadow_counted::*;
76 /// let mut iter = vec![1, 2, 3].into_iter().shadow_counted();
77 /// while let Some(_) = iter.next() {}
78 /// assert_eq!(iter.counter(), 3);
79 /// ```
80 pub fn new(iter: I) -> Self {
81 Self {
82 iter,
83 counter: ShadowCounter::new(),
84 }
85 }
86}
87
88impl<'a, I: Iterator, S> ShadowCountedIter<'a, I, S> {
89 /// Creates a new ShadowCountedIter from an iterator with specific supplemental data.
90 ///
91 /// # Example
92 ///
93 /// ```
94 /// # use shadow_counted::*;
95 /// #[derive(Clone, Default)]
96 /// struct MyData { value: u32 }
97 /// impl Commit for MyData {
98 /// fn commit(&self, _from: Self) {}
99 /// }
100 ///
101 /// let mut iter = vec![1, 2, 3].into_iter();
102 /// let mut iter = ShadowCountedIter::new_with(iter, MyData { value: 42 });
103 /// assert_eq!(iter.supplement().value, 42);
104 /// while let Some(_) = iter.next() {}
105 /// assert_eq!(iter.counter(), 3);
106 /// ```
107 pub fn new_with(iter: I, supplement: S) -> Self {
108 Self {
109 iter,
110 counter: ShadowCounter::new_with_data(supplement),
111 }
112 }
113
114 /// Get a reference to the supplemental data.
115 ///
116 /// # Example
117 ///
118 /// ```
119 /// # use shadow_counted::*;
120 /// #[derive(Clone, Default)]
121 /// struct MyData { value: u32 }
122 /// impl Commit for MyData {
123 /// fn commit(&self, _from: Self) {}
124 /// }
125 ///
126 /// let mut iter = ShadowCountedIter::new_with(vec![1, 2].into_iter(), MyData { value: 42 });
127 /// assert_eq!(iter.supplement().value, 42);
128 /// ```
129 pub fn supplement(&self) -> &S {
130 &self.counter.data
131 }
132
133 /// Get a mutable reference to the supplemental data.
134 ///
135 /// # Example
136 ///
137 /// ```
138 /// # use shadow_counted::*;
139 /// #[derive(Clone, Default)]
140 /// struct MyData { value: u32 }
141 /// impl Commit for MyData {
142 /// fn commit(&self, _from: Self) {}
143 /// }
144 ///
145 /// let mut iter = ShadowCountedIter::new_with(vec![1, 2].into_iter(), MyData { value: 42 });
146 /// iter.supplement_mut().value = 100;
147 /// assert_eq!(iter.supplement().value, 100);
148 /// ```
149 pub fn supplement_mut(&mut self) -> &mut S {
150 &mut self.counter.data
151 }
152}
153
154impl<'a, I: Iterator, S: Clone> ShadowCountedIter<'a, I, S> {
155 /// Creates a new nested `ShadowCountedIter` with a reference to a parent iterator.
156 /// Nested iterators must be either committed to propagate their count to the parent.
157 /// The supplemental data is cloned from the parent.
158 ///
159 /// # Arguments
160 ///
161 /// * `parent` - The parent iterator to commit the count to.
162 ///
163 /// # Example
164 ///
165 /// ```
166 /// # use shadow_counted::*;
167 /// let mut parent_iter = vec![1, 2, 3].into_iter().shadow_counted();
168 /// parent_iter.next();
169 /// # assert_eq!(parent_iter.counter(), 1);
170 ///
171 /// let mut nested_iter = vec![4,5].into_iter().nested_shadow_counted(&mut parent_iter);
172 /// assert_eq!(nested_iter.counter(), 1);
173 /// while let Some(_) = nested_iter.next() {}
174 /// assert_eq!(nested_iter.counter(), 3);
175 /// // destroy the nested iter while committing the count to the parent
176 /// nested_iter.commit();
177 /// # assert_eq!(parent_iter.counter(), 3);
178 ///
179 /// while let Some(_) = parent_iter.next() {}
180 /// assert_eq!(parent_iter.counter(), 5);
181 /// ```
182 pub fn new_nested<'b, T: Iterator>(
183 iter: I,
184 parent: &'a mut ShadowCountedIter<'b, T, S>,
185 ) -> Self {
186 Self {
187 iter,
188 counter: parent.counter.nest(),
189 }
190 }
191}
192
193impl<'a, I: Iterator, S> ShadowCountedIter<'a, I, S> {
194 /// Creates a new nested `ShadowCountedIter` with a reference to a parent iterator
195 /// and custom supplemental data.
196 /// Nested iterators must be either committed to propagate their count to the parent.
197 ///
198 /// # Arguments
199 ///
200 /// * `iter` - The iterator to wrap
201 /// * `parent` - The parent iterator to commit the count to
202 /// * `supplement` - Custom supplemental data for this nested iterator
203 ///
204 /// # Example
205 ///
206 /// ```
207 /// # use shadow_counted::*;
208 /// use std::cell::Cell;
209 ///
210 /// #[derive(Clone, Default, Debug)]
211 /// struct Counter { count: Cell<u32> }
212 /// impl Commit for Counter {
213 /// fn commit(&self, from: Self) {
214 /// self.count.set(self.count.get() + from.count.get());
215 /// }
216 /// }
217 ///
218 /// let mut parent = ShadowCountedIter::new_with(
219 /// vec![1, 2].into_iter(),
220 /// Counter { count: Cell::new(10) }
221 /// );
222 /// parent.next();
223 ///
224 /// let mut nested = ShadowCountedIter::new_nested_with(
225 /// vec![3, 4].into_iter(),
226 /// &mut parent,
227 /// Counter { count: Cell::new(100) }
228 /// );
229 /// assert_eq!(nested.supplement().count.get(), 100); // Custom data, not cloned from parent
230 /// while let Some(_) = nested.next() {}
231 /// nested.commit().unwrap();
232 /// ```
233 pub fn new_nested_with<'b, T: Iterator>(
234 iter: I,
235 parent: &'a mut ShadowCountedIter<'b, T, S>,
236 supplement: S,
237 ) -> Self
238 where
239 S: Clone,
240 {
241 Self {
242 iter,
243 counter: parent.counter.nest_with(supplement),
244 }
245 }
246}
247
248impl<'a, I: Iterator, S: Commit> ShadowCountedIter<'a, I, S> {
249 /// Commits the count of a nested iterator to the parent iterator.
250 /// This destroys `self` while committing the count to the parent.
251 /// Only one child can commit to a parent in case these children got cloned.
252 /// Any further commit will result in an error. Committing to a non nested (top level)
253 /// iterator will error too. On error the iterator is returned.
254 ///
255 /// # Example
256 ///
257 /// ```
258 /// # use shadow_counted::*;
259 /// let mut parent = vec![1, 2].into_iter().shadow_counted();
260 /// parent.next();
261 /// assert_eq!(parent.counter(), 1);
262 ///
263 /// let mut nested = vec![3, 4].into_iter().nested_shadow_counted(&mut parent);
264 /// nested.next();
265 /// nested.next();
266 /// assert_eq!(nested.counter(), 3);
267 ///
268 /// // Commit propagates count to parent
269 /// nested.commit().unwrap();
270 /// assert_eq!(parent.counter(), 3);
271 /// ```
272 pub fn commit(self) -> Result<(), Self> {
273 let Self { iter, counter } = self;
274 counter.commit().map_err(|counter| Self { iter, counter })
275 }
276
277 /// This destructures the `ShadowCountedIter` and returns the iterator it wrapped.
278 /// This is useful when the counter is no longer needed but the inner iterator is and one wants
279 /// to shed the lifetime that comes with the `ShadowCountedIter`.
280 ///
281 /// # Example
282 ///
283 /// ```
284 /// # use shadow_counted::*;
285 /// let mut iter = vec![1, 2, 3, 4, 5].into_iter().shadow_counted();
286 /// iter.next(); // consume one
287 ///
288 /// let inner = iter.into_inner_iter();
289 /// assert_eq!(inner.collect::<Vec<_>>(), vec![2, 3, 4, 5]);
290 /// ```
291 pub fn into_inner_iter(self) -> I {
292 self.iter
293 }
294}
295
296impl<I: Iterator, S> ShadowCountedIter<'_, I, S> {
297 /// Allows to adjust the counter. This is required when in recursive structures only
298 /// leafs shall be counted. Takes an isize so that it can be used with negative values.
299 ///
300 /// # Arguments
301 ///
302 /// * `delta` - The delta to adjust the counter by.
303 ///
304 /// # Example
305 ///
306 /// ```
307 /// # use shadow_counted::*;
308 /// let mut iter = vec![1, 2, 3].into_iter().shadow_counted();
309 /// iter.add(2);
310 /// assert_eq!(iter.counter(), 2);
311 /// iter.add(-1);
312 /// assert_eq!(iter.counter(), 1);
313 /// ```
314 #[inline]
315 pub fn add(&mut self, delta: isize) {
316 self.counter.add(delta)
317 }
318
319 /// Returns the iterators current count.
320 ///
321 /// # Example
322 ///
323 /// ```
324 /// # use shadow_counted::*;
325 /// let vec = vec![1, 2, 3];
326 /// let mut iter = vec.into_iter().shadow_counted();
327 /// while let Some(_) = iter.next() {}
328 /// assert_eq!(iter.counter(), 3);
329 /// ```
330 #[inline]
331 pub fn counter(&self) -> usize {
332 self.counter.get()
333 }
334}
335
336impl<I: Iterator, S> Iterator for ShadowCountedIter<'_, I, S> {
337 type Item = I::Item;
338
339 fn next(&mut self) -> Option<Self::Item> {
340 match self.iter.next() {
341 Some(item) => {
342 *self.counter.counter.get_mut() += 1;
343 Some(item)
344 }
345 None => None,
346 }
347 }
348}
349
350impl<I: Iterator, S> AsRef<I> for ShadowCountedIter<'_, I, S> {
351 fn as_ref(&self) -> &I {
352 &self.iter
353 }
354}
355
356/// Implements `ExactSizeIterator` when the inner iterator does.
357/// The length reflects the remaining items in the iterator.
358///
359/// # Example
360///
361/// ```
362/// # use shadow_counted::*;
363/// let mut iter = vec![1, 2, 3, 4, 5].into_iter().shadow_counted();
364/// assert_eq!(iter.len(), 5);
365/// iter.next();
366/// assert_eq!(iter.len(), 4);
367/// iter.next();
368/// assert_eq!(iter.len(), 3);
369/// ```
370impl<I: Iterator + ExactSizeIterator, S> ExactSizeIterator for ShadowCountedIter<'_, I, S> {
371 fn len(&self) -> usize {
372 self.iter.len()
373 }
374}
375
376impl<I: Iterator + std::iter::FusedIterator, S> std::iter::FusedIterator
377 for ShadowCountedIter<'_, I, S>
378{
379}
380
381/// Implements `DoubleEndedIterator` when the inner iterator does.
382/// Both forward and backward iteration increment the counter.
383///
384/// # Example
385///
386/// ```
387/// # use shadow_counted::*;
388/// let mut iter = vec![1, 2, 3, 4, 5].into_iter().shadow_counted();
389/// assert_eq!(iter.next(), Some(1));
390/// assert_eq!(iter.counter(), 1);
391/// assert_eq!(iter.next_back(), Some(5));
392/// assert_eq!(iter.counter(), 2);
393/// assert_eq!(iter.next_back(), Some(4));
394/// assert_eq!(iter.counter(), 3);
395/// ```
396impl<I: DoubleEndedIterator, S> DoubleEndedIterator for ShadowCountedIter<'_, I, S> {
397 fn next_back(&mut self) -> Option<Self::Item> {
398 match self.iter.next_back() {
399 Some(item) => {
400 *self.counter.counter.get_mut() += 1;
401 Some(item)
402 }
403 None => None,
404 }
405 }
406}
407
408/// A extension trait to convert any iterator into a ShadowCountedIter.
409/// This must be in scope to use the `shadow_counted` method on an iterator.
410/// When possible the `From` and `Into` may be more convenient to use.
411///
412/// # Example
413///
414/// ```
415/// # use shadow_counted::*;
416/// let vec = vec![1, 2, 3];
417/// let mut iter = vec.into_iter().shadow_counted();
418/// while let Some(_) = iter.next() {}
419/// assert_eq!(iter.counter(), 3);
420/// ```
421pub trait IntoShadowCounted {
422 /// Converts the iterator into a ShadowCountedIter with default (unit) supplemental data.
423 fn shadow_counted<'a>(self) -> ShadowCountedIter<'a, Self, ()>
424 where
425 Self: Sized + Iterator,
426 {
427 ShadowCountedIter::new(self)
428 }
429
430 /// Converts the iterator into a nested ShadowCountedIter.
431 ///
432 /// # Arguments
433 ///
434 /// * `parent` - The parent iterator to commit the count to.
435 ///
436 /// # Example
437 ///
438 /// ```
439 /// # use shadow_counted::*;
440 /// let mut parent = vec![1, 2, 3].into_iter().shadow_counted();
441 /// parent.next();
442 ///
443 /// let mut nested = vec![4, 5].into_iter().nested_shadow_counted(&mut parent);
444 /// assert_eq!(nested.counter(), 1); // Inherits parent's count
445 /// for _ in nested.by_ref() {}
446 /// nested.commit().unwrap();
447 /// assert_eq!(parent.counter(), 3); // Parent now has nested count
448 /// ```
449 fn nested_shadow_counted<'a, I: Iterator, S: Clone>(
450 self,
451 parent: &'a mut ShadowCountedIter<'_, I, S>,
452 ) -> ShadowCountedIter<'a, Self, S>
453 where
454 Self: Sized + Iterator,
455 {
456 ShadowCountedIter::new_nested(self, parent)
457 }
458}
459
460impl<T: Iterator> IntoShadowCounted for T {}
461
462/// When types can be inferred then `From` and `Into` can be used to convert an iterator into a
463/// `ShadowCountedIter` with default (unit) supplemental data.
464impl<T: Iterator> From<T> for ShadowCountedIter<'_, T, ()> {
465 fn from(iter: T) -> Self {
466 ShadowCountedIter::new(iter)
467 }
468}
469
470/// A shadow counter that can commit its count to a parent counter.
471/// Carries supplemental data of type S.
472#[derive(Debug, Clone)]
473struct ShadowCounter<'a, S = ()> {
474 /// holds the current count including counts from children who committed here
475 counter: Cell<usize>,
476 /// the parents counter when this child was created
477 created_at: usize,
478 /// parent for nested counters
479 parent: Option<&'a ShadowCounter<'a, S>>,
480 /// supplemental data
481 data: S,
482}
483
484impl<'a, S: Clone> ShadowCounter<'a, S> {
485 fn nest(&'a self) -> Self {
486 Self {
487 counter: self.counter.clone(),
488 created_at: self.counter.get(),
489 parent: Some(self),
490 data: self.data.clone(),
491 }
492 }
493
494 fn nest_with(&'a self, data: S) -> Self {
495 Self {
496 counter: self.counter.clone(),
497 created_at: self.counter.get(),
498 parent: Some(self),
499 data,
500 }
501 }
502}
503
504impl<S: Default> ShadowCounter<'_, S> {
505 fn new() -> Self {
506 Self {
507 counter: 0.into(),
508 created_at: 0,
509 parent: None,
510 data: S::default(),
511 }
512 }
513}
514
515impl<S> ShadowCounter<'_, S> {
516 fn new_with_data(data: S) -> Self {
517 Self {
518 counter: 0.into(),
519 created_at: 0,
520 parent: None,
521 data,
522 }
523 }
524
525 #[inline]
526 fn get(&self) -> usize {
527 self.counter.get()
528 }
529
530 #[inline]
531 fn add(&mut self, delta: isize) {
532 self.counter
533 .set(self.counter.get().wrapping_add(delta as usize));
534 }
535}
536
537impl<S: Commit> ShadowCounter<'_, S> {
538 fn commit(self) -> Result<(), Self> {
539 if let Some(p) = self.parent {
540 if p.counter.get() == self.created_at {
541 p.counter.set(self.counter.get());
542 // Commit supplemental data to parent
543 // Parent is responsible for interior mutability
544 p.data.commit(self.data);
545 return Ok(());
546 }
547 }
548 Err(self)
549 }
550}
551
552#[cfg(test)]
553mod tests {
554 use super::*;
555
556 #[test]
557 fn test_empty() {
558 let vec: Vec<i32> = vec![];
559 let mut iter: ShadowCountedIter<'_, _, ()> = ShadowCountedIter::new(vec.into_iter());
560 while iter.next().is_some() {}
561 assert_eq!(iter.counter(), 0);
562 }
563
564 #[test]
565 fn commit_nonnested() {
566 let vec: Vec<i32> = vec![];
567 let mut iter: ShadowCountedIter<'_, _, ()> = ShadowCountedIter::new(vec.into_iter());
568 while iter.next().is_some() {}
569 assert!(iter.commit().is_err());
570 }
571
572 #[test]
573 fn test_basic_counting() {
574 let vec = vec![1, 2, 3];
575 let mut iter: ShadowCountedIter<'_, _, ()> = ShadowCountedIter::new(vec.into_iter());
576 while iter.next().is_some() {}
577 assert_eq!(iter.counter(), 3);
578 }
579
580 #[test]
581 fn test_empty_iterator() {
582 let vec: Vec<i32> = vec![];
583 let mut iter: ShadowCountedIter<'_, _, ()> = ShadowCountedIter::new(vec.into_iter());
584 while iter.next().is_some() {}
585 assert_eq!(iter.counter(), 0);
586 }
587
588 #[test]
589 fn test_commit() {
590 let mut parent_iter = vec![1, 2, 3].into_iter().shadow_counted();
591 parent_iter.next();
592 let mut nested_iter = vec![4, 5]
593 .into_iter()
594 .nested_shadow_counted(&mut parent_iter);
595 nested_iter.next();
596 nested_iter.commit().unwrap();
597 assert_eq!(parent_iter.counter(), 2);
598 }
599
600 #[test]
601 fn test_commit_twice() {
602 let mut parent_iter = vec![1, 2, 3].into_iter().shadow_counted();
603 parent_iter.next();
604 let mut nested_iter = vec![4, 5]
605 .into_iter()
606 .nested_shadow_counted(&mut parent_iter);
607 let nested_iter2 = nested_iter.clone();
608 nested_iter.next();
609 nested_iter.commit().unwrap();
610 assert!(nested_iter2.commit().is_err());
611 assert_eq!(parent_iter.counter(), 2);
612 }
613
614 #[test]
615 fn test_two_commits() {
616 let mut parent_iter = vec![1, 2, 3].into_iter().shadow_counted();
617 parent_iter.next();
618 let mut nested_iter = vec![4].into_iter().nested_shadow_counted(&mut parent_iter);
619 nested_iter.next();
620 nested_iter.commit().unwrap();
621 parent_iter.next();
622
623 // next nested iter
624 let mut nested_iter = vec![5].into_iter().nested_shadow_counted(&mut parent_iter);
625 nested_iter.next();
626 nested_iter.commit().unwrap();
627
628 parent_iter.next();
629 assert_eq!(parent_iter.counter(), 5);
630 }
631
632 #[test]
633 fn test_shadow_count_iter() {
634 #[derive(Debug, PartialEq)]
635 enum Nodes<'a, T> {
636 Leaf(T),
637 Nested(&'a [Nodes<'a, T>]),
638 }
639
640 let items = &[
641 Nodes::Leaf(1),
642 Nodes::Leaf(2),
643 Nodes::Nested(&[Nodes::Leaf(3), Nodes::Leaf(4), Nodes::Leaf(5)]),
644 Nodes::Leaf(6),
645 ];
646
647 let mut sc_iter = items.iter().shadow_counted();
648
649 assert!((sc_iter.counter()) == (0));
650 assert!((sc_iter.next()) == (Some(&Nodes::Leaf(1))));
651 assert!((sc_iter.counter()) == (1));
652 assert!((sc_iter.next()) == (Some(&Nodes::Leaf(2))));
653 assert!((sc_iter.counter()) == (2));
654
655 let nested = sc_iter.next().unwrap();
656 assert!((sc_iter.counter()) == (3));
657 assert!((nested) == (&Nodes::Nested(&[Nodes::Leaf(3), Nodes::Leaf(4), Nodes::Leaf(5)])));
658 let Nodes::Nested(nested) = nested else {
659 panic!()
660 };
661 let mut nested_iter = nested.iter().nested_shadow_counted(&mut sc_iter);
662 assert_eq!(nested_iter.counter(), 3);
663 assert_eq!(nested_iter.next(), Some(&Nodes::Leaf(3)));
664 assert_eq!(nested_iter.counter(), 4);
665 assert_eq!(nested_iter.next(), Some(&Nodes::Leaf(4)));
666 assert_eq!(nested_iter.counter(), 5);
667 assert_eq!(nested_iter.next(), Some(&Nodes::Leaf(5)));
668 assert_eq!(nested_iter.counter(), 6);
669 assert_eq!(nested_iter.next(), None);
670 assert_eq!(nested_iter.counter(), 6);
671 nested_iter.commit().unwrap();
672 assert_eq!(sc_iter.counter(), 6);
673 assert_eq!(sc_iter.next(), Some(&Nodes::Leaf(6)));
674 assert_eq!(sc_iter.counter(), 7);
675 }
676
677 #[test]
678 fn test_supplement_with_custom_data() {
679 #[derive(Debug, Clone, Default, PartialEq)]
680 struct MyData {
681 value: u32,
682 }
683 impl Commit for MyData {
684 fn commit(&self, _from: Self) {}
685 }
686
687 let vec = vec![1, 2, 3];
688 let data = MyData { value: 42 };
689 let mut iter = ShadowCountedIter::new_with(vec.into_iter(), data);
690 assert_eq!(iter.supplement().value, 42);
691 while iter.next().is_some() {}
692 assert_eq!(iter.counter(), 3);
693 assert_eq!(iter.supplement().value, 42);
694 }
695
696 #[test]
697 fn test_supplement_mut() {
698 #[derive(Debug, Clone, Default, PartialEq)]
699 struct MyData {
700 value: u32,
701 }
702 impl Commit for MyData {
703 fn commit(&self, _from: Self) {}
704 }
705
706 let mut iter = ShadowCountedIter::new_with(vec![1, 2].into_iter(), MyData { value: 10 });
707 assert_eq!(iter.supplement().value, 10);
708 iter.supplement_mut().value = 20;
709 assert_eq!(iter.supplement().value, 20);
710 }
711
712 #[test]
713 fn test_nested_data_cloned() {
714 #[derive(Debug, Clone, Default, PartialEq)]
715 struct MyData {
716 value: u32,
717 }
718 impl Commit for MyData {
719 fn commit(&self, _from: Self) {}
720 }
721
722 let mut parent = ShadowCountedIter::new_with(vec![1].into_iter(), MyData { value: 42 });
723
724 let nested = vec![2].into_iter().nested_shadow_counted(&mut parent);
725 assert_eq!(nested.supplement().value, 42); // Cloned from parent
726 }
727
728 #[test]
729 fn test_data_committed() {
730 use std::cell::Cell;
731
732 #[derive(Debug, Clone, Default)]
733 struct Counter {
734 count: Cell<u32>,
735 }
736
737 impl Commit for Counter {
738 fn commit(&self, from: Self) {
739 self.count.set(self.count.get() + from.count.get());
740 }
741 }
742
743 let mut parent = ShadowCountedIter::new_with(vec![1, 2].into_iter(), Counter::default());
744 parent.next();
745
746 let mut nested = vec![3, 4].into_iter().nested_shadow_counted(&mut parent);
747 nested.supplement_mut().count.set(5);
748 nested.next();
749 nested.next();
750 nested.commit().unwrap();
751
752 assert_eq!(parent.supplement().count.get(), 5); // Committed from nested
753 }
754}