gat_lending_iterator/adapters/
fuse.rs1use crate::LendingIterator;
2use core::fmt;
3
4#[derive(Clone)]
13#[must_use = "iterators are lazy and do nothing unless consumed"]
14pub struct Fuse<I> {
15 iter: Option<I>,
16}
17
18impl<I> Fuse<I> {
19 pub(crate) fn new(iter: I) -> Self {
20 Self { iter: Some(iter) }
21 }
22}
23
24impl<I: fmt::Debug> fmt::Debug for Fuse<I> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 f.debug_struct("Fuse").field("iter", &self.iter).finish()
27 }
28}
29
30impl<I> LendingIterator for Fuse<I>
31where
32 I: LendingIterator,
33{
34 type Item<'a>
35 = I::Item<'a>
36 where
37 Self: 'a;
38
39 #[inline]
40 fn next(&mut self) -> Option<Self::Item<'_>> {
41 let self_ = unsafe { &mut *(self as *mut Self) };
43 let iter = self_.iter.as_mut()?;
44 if let Some(item) = iter.next() {
45 Some(item)
46 } else {
47 self.iter = None;
48 None
49 }
50 }
51
52 #[inline]
53 #[allow(clippy::redundant_closure_for_method_calls)]
54 fn size_hint(&self) -> (usize, Option<usize>) {
55 self.iter
56 .as_ref()
57 .map_or((0, Some(0)), |iter| iter.size_hint())
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use crate::{LendingIterator, ToLendingIterator};
64
65 struct OneThenError {
66 yielded: bool,
67 }
68
69 impl OneThenError {
70 fn new() -> Self {
71 Self { yielded: false }
72 }
73 }
74
75 impl LendingIterator for OneThenError {
76 type Item<'a>
77 = i32
78 where
79 Self: 'a;
80
81 fn next(&mut self) -> Option<Self::Item<'_>> {
82 if self.yielded {
83 None
84 } else {
85 self.yielded = true;
86 Some(1)
87 }
88 }
89 }
90
91 fn identity(x: i32) -> i32 {
92 x
93 }
94
95 #[test]
96 fn fuse_basic() {
97 let mut iter = OneThenError::new().fuse();
98 assert_eq!(iter.next(), Some(1));
99 assert_eq!(iter.next(), None);
100 assert_eq!(iter.next(), None);
101 assert_eq!(iter.next(), None);
102 }
103
104 #[test]
105 fn fuse_regular_iter() {
106 let result: Vec<_> = (0..5)
107 .into_lending()
108 .fuse()
109 .map(identity)
110 .into_iter()
111 .collect();
112 assert_eq!(result, vec![0, 1, 2, 3, 4]);
113 }
114}