lender/sources/
once_with.rs

1use crate::{higher_order::FnOnceHKA, DoubleEndedLender, ExactSizeLender, FusedLender, Lend, Lender, Lending};
2
3/// Creates an lender that lazily generates a value exactly once by invoking
4/// the provided closure.
5/// # Examples
6/// ```rust
7/// # use lender::prelude::*;
8/// let mut lender = lender::once_with(0u8, hrc_once!(for<'all> |state: &'all mut u8| -> &'all mut u8 {
9///     *state += 1;
10///     state
11/// }));
12/// assert_eq!(lender.next(), Some(&mut 1));
13/// assert_eq!(lender.next(), None);
14/// ```
15pub fn once_with<St, F>(state: St, f: F) -> OnceWith<St, F>
16where
17    F: for<'all> FnOnceHKA<'all, &'all mut St>,
18{
19    OnceWith { state, f: Some(f) }
20}
21
22/// An iterator that yields a single element of type `A` by
23/// applying the provided closure `F: FnOnce() -> A`.
24///
25/// This `struct` is created by the [`once_with()`] function.
26///
27pub struct OnceWith<St, F> {
28    state: St,
29    f: Option<F>,
30}
31
32impl<'lend, St, F> Lending<'lend> for OnceWith<St, F>
33where
34    F: for<'all> FnOnceHKA<'all, &'all mut St>,
35{
36    type Lend = <F as FnOnceHKA<'lend, &'lend mut St>>::B;
37}
38
39impl<St, F> Lender for OnceWith<St, F>
40where
41    F: for<'all> FnOnceHKA<'all, &'all mut St>,
42{
43    #[inline]
44    fn next(&mut self) -> Option<Lend<'_, Self>> {
45        self.f.take().map(|f| f(&mut self.state))
46    }
47    #[inline]
48    fn size_hint(&self) -> (usize, Option<usize>) {
49        if self.f.is_some() {
50            (1, Some(1))
51        } else {
52            (0, Some(0))
53        }
54    }
55}
56
57impl<St, F> DoubleEndedLender for OnceWith<St, F>
58where
59    F: for<'all> FnOnceHKA<'all, &'all mut St>,
60{
61    #[inline]
62    fn next_back(&mut self) -> Option<Lend<'_, Self>> {
63        self.next()
64    }
65}
66
67impl<St, F> ExactSizeLender for OnceWith<St, F>
68where
69    F: for<'all> FnOnceHKA<'all, &'all mut St>,
70{
71    #[inline]
72    fn len(&self) -> usize {
73        self.size_hint().0
74    }
75}
76
77impl<St, F> FusedLender for OnceWith<St, F> where F: for<'all> FnOnceHKA<'all, &'all mut St> {}