lender/adapters/
enumerate.rs1use core::num::NonZeroUsize;
2
3use crate::{
4 DoubleEndedLender, ExactSizeLender, FusedLender, Lend, Lender, Lending, try_trait_v2::Try,
5};
6
7#[derive(Clone, Debug)]
12#[must_use = "lenders are lazy and do nothing unless consumed"]
13pub struct Enumerate<L> {
14 pub(crate) lender: L,
15 pub(crate) count: usize,
16}
17
18impl<L> Enumerate<L> {
19 #[inline(always)]
21 pub fn into_inner(self) -> L {
22 self.lender
23 }
24
25 #[inline(always)]
27 pub fn into_parts(self) -> (L, usize) {
28 (self.lender, self.count)
29 }
30}
31
32impl<L: Lender> Enumerate<L> {
33 #[inline(always)]
34 pub(crate) fn new(lender: L) -> Enumerate<L> {
35 let _ = L::__check_covariance(crate::CovariantProof::new());
36 Enumerate { lender, count: 0 }
37 }
38}
39
40impl<'lend, L> Lending<'lend> for Enumerate<L>
41where
42 L: Lender,
43{
44 type Lend = (usize, Lend<'lend, L>);
45}
46
47impl<L> Lender for Enumerate<L>
48where
49 L: Lender,
50{
51 crate::unsafe_assume_covariance!();
53 #[inline]
54 fn next(&mut self) -> Option<Lend<'_, Self>> {
55 self.lender.next().map(|x| {
56 let count = self.count;
57 self.count += 1;
58 (count, x)
59 })
60 }
61
62 #[inline(always)]
63 fn size_hint(&self) -> (usize, Option<usize>) {
64 self.lender.size_hint()
65 }
66
67 #[inline]
68 fn nth(&mut self, n: usize) -> Option<Lend<'_, Self>> {
69 let a = self.lender.nth(n)?;
70 let i = self.count + n;
72 self.count = i + 1;
73 Some((i, a))
74 }
75
76 #[inline(always)]
77 fn count(self) -> usize {
78 self.lender.count()
79 }
80
81 #[inline]
82 fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
83 where
84 Self: Sized,
85 F: FnMut(B, Lend<'_, Self>) -> R,
86 R: Try<Output = B>,
87 {
88 let count = &mut self.count;
89 self.lender.try_fold(init, |acc, x| {
90 let elt = (*count, x);
91 *count += 1;
92 f(acc, elt)
93 })
94 }
95
96 #[inline]
97 fn fold<B, F>(self, init: B, mut f: F) -> B
98 where
99 Self: Sized,
100 F: FnMut(B, Lend<'_, Self>) -> B,
101 {
102 let mut count = self.count;
103 self.lender.fold(init, |acc, x| {
104 let elt = (count, x);
105 count += 1;
106 f(acc, elt)
107 })
108 }
109
110 #[inline]
111 fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
112 let remaining = self.lender.advance_by(n);
113 let advanced = match remaining {
114 Ok(()) => n,
115 Err(rem) => n - rem.get(),
116 };
117 self.count += advanced;
118 remaining
119 }
120}
121
122impl<L> DoubleEndedLender for Enumerate<L>
123where
124 L: ExactSizeLender + DoubleEndedLender,
125{
126 #[inline]
127 fn next_back(&mut self) -> Option<Lend<'_, Self>> {
128 let len = self.lender.len();
129 let x = self.lender.next_back()?;
130 Some((self.count + len - 1, x))
131 }
132
133 #[inline]
134 fn nth_back(&mut self, n: usize) -> Option<Lend<'_, Self>> {
135 let len = self.lender.len();
136 let x = self.lender.nth_back(n)?;
137 Some((self.count + len - n - 1, x))
138 }
139
140 #[inline]
141 fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
142 where
143 Self: Sized,
144 F: FnMut(B, Lend<'_, Self>) -> R,
145 R: Try<Output = B>,
146 {
147 let mut count = self.count + self.lender.len();
148 self.lender.try_rfold(init, move |acc, x| {
149 count -= 1;
150 f(acc, (count, x))
151 })
152 }
153
154 #[inline]
155 fn rfold<B, F>(self, init: B, mut f: F) -> B
156 where
157 Self: Sized,
158 F: FnMut(B, Lend<'_, Self>) -> B,
159 {
160 let mut count = self.count + self.lender.len();
161 self.lender.rfold(init, move |acc, x| {
162 count -= 1;
163 f(acc, (count, x))
164 })
165 }
166
167 #[inline(always)]
168 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
169 self.lender.advance_back_by(n)
170 }
171}
172
173impl<L> ExactSizeLender for Enumerate<L>
174where
175 L: ExactSizeLender,
176{
177 #[inline(always)]
178 fn len(&self) -> usize {
179 self.lender.len()
180 }
181
182 #[inline(always)]
183 fn is_empty(&self) -> bool {
184 self.lender.is_empty()
185 }
186}
187
188impl<L> FusedLender for Enumerate<L> where L: FusedLender {}
189
190impl<L: Default + Lender> Default for Enumerate<L> {
191 #[inline(always)]
192 fn default() -> Self {
193 Enumerate::new(Default::default())
194 }
195}