lender/fallible_adapters/
chunky.rs1use crate::{
2 Chunk, Chunky, FallibleLend, FallibleLender, FallibleLending, FusedFallibleLender,
3 try_trait_v2::Try,
4};
5use core::ops::ControlFlow;
6
7impl<'lend, L> FallibleLending<'lend> for Chunky<L>
8where
9 L: FallibleLender,
10{
11 type Lend = Chunk<'lend, L>;
12}
13
14impl<L> FallibleLender for Chunky<L>
15where
16 L: FallibleLender,
17{
18 type Error = L::Error;
19 crate::unsafe_assume_covariance_fallible!();
21
22 #[inline]
23 fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
24 if self.len > 0 {
25 self.len -= 1;
26 Ok(Some(self.lender.next_chunk(self.chunk_size)))
27 } else {
28 Ok(None)
29 }
30 }
31
32 #[inline]
33 fn nth(&mut self, n: usize) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
34 if n < self.len {
35 let skip = n
37 .checked_mul(self.chunk_size)
38 .expect("overflow in Chunky::nth");
39 self.len -= n;
40 if self.lender.advance_by(skip)?.is_err() {
41 unreachable!();
42 }
43 self.next()
44 } else {
45 if self.len > 0 {
47 let skip = self
48 .len
49 .checked_mul(self.chunk_size)
50 .expect("overflow in Chunky::nth");
51 let _ = self.lender.advance_by(skip)?;
52 self.len = 0;
53 }
54 Ok(None)
55 }
56 }
57
58 #[inline]
59 fn size_hint(&self) -> (usize, Option<usize>) {
60 (self.len, Some(self.len))
61 }
62
63 #[inline]
64 fn count(self) -> Result<usize, Self::Error> {
65 Ok(self.len)
66 }
67
68 #[inline]
69 fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
70 where
71 Self: Sized,
72 F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
73 R: Try<Output = B>,
74 {
75 let mut acc = init;
76 let sz = self.chunk_size;
77 while self.len > 0 {
78 self.len -= 1;
79 acc = match f(acc, self.lender.next_chunk(sz))?.branch() {
80 ControlFlow::Break(x) => return Ok(R::from_residual(x)),
81 ControlFlow::Continue(x) => x,
82 };
83 }
84 Ok(R::from_output(acc))
85 }
86
87 #[inline]
88 fn fold<B, F>(mut self, init: B, mut f: F) -> Result<B, Self::Error>
89 where
90 Self: Sized,
91 F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
92 {
93 let mut accum = init;
94 let sz = self.chunk_size;
95 while self.len > 0 {
96 self.len -= 1;
97 accum = f(accum, self.lender.next_chunk(sz))?;
98 }
99 Ok(accum)
100 }
101}
102
103impl<L> FusedFallibleLender for Chunky<L> where L: FusedFallibleLender {}