Skip to main content

lender/fallible_adapters/
into_fallible.rs

1use core::{convert::Infallible, num::NonZeroUsize};
2
3use crate::{
4    DoubleEndedFallibleLender, DoubleEndedLender, ExactSizeFallibleLender, ExactSizeLender,
5    FallibleLend, FallibleLender, FallibleLending, FusedFallibleLender, FusedLender, Lender,
6    Lending,
7};
8
9/// A fallible lender that wraps a normal lender.
10///
11/// The error type is always [`Infallible`] since the underlying
12/// lender cannot fail.
13#[derive(Clone, Debug)]
14#[repr(transparent)]
15#[must_use = "lenders are lazy and do nothing unless consumed"]
16pub struct IntoFallible<L> {
17    pub(crate) lender: L,
18}
19
20impl<L: crate::Lender> IntoFallible<L> {
21    #[inline(always)]
22    pub(crate) fn new(lender: L) -> Self {
23        let _ = L::__check_covariance(crate::CovariantProof::new());
24        Self { lender }
25    }
26
27    /// Returns the inner lender.
28    #[inline(always)]
29    pub fn into_inner(self) -> L {
30        self.lender
31    }
32}
33
34impl<'lend, L> FallibleLending<'lend> for IntoFallible<L>
35where
36    L: Lending<'lend>,
37{
38    type Lend = L::Lend;
39}
40
41impl<L> FallibleLender for IntoFallible<L>
42where
43    L: Lender,
44{
45    type Error = Infallible;
46    // SAFETY: the lend is that of L
47    crate::unsafe_assume_covariance_fallible!();
48
49    #[inline]
50    fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
51        Ok(self.lender.next())
52    }
53
54    #[inline(always)]
55    fn size_hint(&self) -> (usize, Option<usize>) {
56        self.lender.size_hint()
57    }
58
59    #[inline]
60    fn nth(&mut self, n: usize) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
61        Ok(self.lender.nth(n))
62    }
63
64    #[inline]
65    fn count(self) -> Result<usize, Self::Error>
66    where
67        Self: Sized,
68    {
69        Ok(self.lender.count())
70    }
71
72    #[inline]
73    fn last(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error>
74    where
75        Self: Sized,
76    {
77        Ok(self.lender.last())
78    }
79
80    #[inline]
81    fn advance_by(&mut self, n: usize) -> Result<Result<(), NonZeroUsize>, Self::Error> {
82        Ok(self.lender.advance_by(n))
83    }
84
85    #[inline]
86    fn fold<B, F>(self, init: B, mut f: F) -> Result<B, Self::Error>
87    where
88        Self: Sized,
89        F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
90    {
91        Ok(self.lender.fold(init, |acc, value| match f(acc, value) {
92            Ok(b) => b,
93            Err(e) => match e {},
94        }))
95    }
96
97    #[inline]
98    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
99    where
100        F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
101        R: stable_try_trait_v2::Try<Output = B>,
102    {
103        // Since Self::Error = Infallible, f can never return Err, so we can
104        // safely unwrap and delegate to the inner lender's try_fold
105        Ok(self.lender.try_fold(init, |acc, value| {
106            // f returns Result<R, Infallible>, which is always Ok
107            match f(acc, value) {
108                Ok(r) => r,
109                Err(e) => match e {},
110            }
111        }))
112    }
113}
114
115impl<L: Lender> From<L> for IntoFallible<L> {
116    #[inline(always)]
117    fn from(lender: L) -> Self {
118        Self::new(lender)
119    }
120}
121
122impl<L> DoubleEndedFallibleLender for IntoFallible<L>
123where
124    L: DoubleEndedLender,
125{
126    #[inline]
127    fn next_back(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
128        Ok(self.lender.next_back())
129    }
130
131    #[inline]
132    fn nth_back(&mut self, n: usize) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
133        Ok(self.lender.nth_back(n))
134    }
135
136    #[inline]
137    fn advance_back_by(&mut self, n: usize) -> Result<Result<(), NonZeroUsize>, Self::Error> {
138        Ok(self.lender.advance_back_by(n))
139    }
140
141    #[inline]
142    fn rfold<B, F>(self, init: B, mut f: F) -> Result<B, Self::Error>
143    where
144        Self: Sized,
145        F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
146    {
147        Ok(self.lender.rfold(init, |acc, value| match f(acc, value) {
148            Ok(b) => b,
149            Err(e) => match e {},
150        }))
151    }
152
153    #[inline]
154    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
155    where
156        F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
157        R: stable_try_trait_v2::Try<Output = B>,
158    {
159        // Since Self::Error = Infallible, f can never return Err
160        Ok(self
161            .lender
162            .try_rfold(init, |acc, value| match f(acc, value) {
163                Ok(r) => r,
164                Err(e) => match e {},
165            }))
166    }
167}
168
169impl<L> ExactSizeFallibleLender for IntoFallible<L>
170where
171    L: ExactSizeLender,
172{
173    #[inline(always)]
174    fn len(&self) -> usize {
175        self.lender.len()
176    }
177
178    #[inline(always)]
179    fn is_empty(&self) -> bool {
180        self.lender.is_empty()
181    }
182}
183
184impl<L> FusedFallibleLender for IntoFallible<L> where L: FusedLender {}