lender/sources/
from_iter_ref.rs1use core::iter::FusedIterator;
2use core::num::NonZeroUsize;
3use core::ops::ControlFlow;
4
5use crate::try_trait_v2::Try;
6use crate::{FusedLender, prelude::*};
7
8#[inline]
29pub fn from_iter_ref<I: Iterator>(iter: I) -> FromIterRef<I> {
30 FromIterRef {
31 iter,
32 current: None,
33 }
34}
35
36#[derive(Clone, Debug)]
42#[must_use = "lenders are lazy and do nothing unless consumed"]
43pub struct FromIterRef<I: Iterator> {
44 iter: I,
45 current: Option<I::Item>,
46}
47
48impl<'lend, I: Iterator> Lending<'lend> for FromIterRef<I> {
49 type Lend = &'lend I::Item;
50}
51
52impl<I: Iterator> Lender for FromIterRef<I> {
53 crate::check_covariance!();
54
55 #[inline]
56 fn next(&mut self) -> Option<Lend<'_, Self>> {
57 self.current = self.iter.next();
58 self.current.as_ref()
59 }
60
61 #[inline(always)]
62 fn size_hint(&self) -> (usize, Option<usize>) {
63 self.iter.size_hint()
64 }
65
66 #[inline]
67 fn nth(&mut self, n: usize) -> Option<Lend<'_, Self>> {
68 self.current = self.iter.nth(n);
69 self.current.as_ref()
70 }
71
72 #[inline(always)]
73 fn count(self) -> usize
74 where
75 Self: Sized,
76 {
77 self.iter.count()
78 }
79
80 #[inline]
81 fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
82 for i in 0..n {
83 if self.iter.next().is_none() {
84 return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
86 }
87 }
88 Ok(())
89 }
90
91 #[inline]
92 fn last<'call>(&'call mut self) -> Option<Lend<'call, Self>>
93 where
94 Self: Sized,
95 {
96 self.current = None;
97 for x in self.iter.by_ref() {
98 self.current = Some(x);
99 }
100 self.current.as_ref()
101 }
102
103 #[inline]
104 fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
105 where
106 F: FnMut(B, Lend<'_, Self>) -> R,
107 R: Try<Output = B>,
108 {
109 let mut acc = init;
110 for item in self.iter.by_ref() {
111 acc = match f(acc, &item).branch() {
112 ControlFlow::Break(x) => return R::from_residual(x),
113 ControlFlow::Continue(x) => x,
114 };
115 }
116 R::from_output(acc)
117 }
118
119 #[inline]
120 fn fold<B, F>(self, init: B, mut f: F) -> B
121 where
122 Self: Sized,
123 F: FnMut(B, Lend<'_, Self>) -> B,
124 {
125 self.iter.fold(init, |acc, item| f(acc, &item))
126 }
127}
128
129impl<I: DoubleEndedIterator> DoubleEndedLender for FromIterRef<I> {
130 #[inline]
131 fn next_back(&mut self) -> Option<Lend<'_, Self>> {
132 self.current = self.iter.next_back();
133 self.current.as_ref()
134 }
135
136 #[inline]
137 fn nth_back(&mut self, n: usize) -> Option<Lend<'_, Self>> {
138 self.current = self.iter.nth_back(n);
139 self.current.as_ref()
140 }
141
142 #[inline]
143 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
144 for i in 0..n {
145 if self.iter.next_back().is_none() {
146 return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
148 }
149 }
150 Ok(())
151 }
152
153 #[inline]
154 fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
155 where
156 F: FnMut(B, Lend<'_, Self>) -> R,
157 R: Try<Output = B>,
158 {
159 let mut acc = init;
160 while let Some(item) = self.iter.next_back() {
161 acc = match f(acc, &item).branch() {
162 ControlFlow::Break(x) => return R::from_residual(x),
163 ControlFlow::Continue(x) => x,
164 };
165 }
166 R::from_output(acc)
167 }
168
169 #[inline]
170 fn rfold<B, F>(self, init: B, mut f: F) -> B
171 where
172 Self: Sized,
173 F: FnMut(B, Lend<'_, Self>) -> B,
174 {
175 self.iter.rfold(init, |acc, item| f(acc, &item))
176 }
177}
178
179impl<I: ExactSizeIterator> ExactSizeLender for FromIterRef<I> {
180 #[inline(always)]
181 fn len(&self) -> usize {
182 self.iter.len()
183 }
184}
185
186impl<I: FusedIterator> FusedLender for FromIterRef<I> {}
187
188impl<I: Iterator> From<I> for FromIterRef<I> {
189 #[inline(always)]
190 fn from(iter: I) -> Self {
191 from_iter_ref(iter)
192 }
193}