lending_iterator/lending_iterator/constructors/
from_fn.rs

1/// Main _ad-hoc_ / closure-based constructor of `LendingIterator`s.
2///
3/// It expects the both necessary and sufficient elements for such an impl:
4///
5///   - a `State`, which will play a role akin to that of `Self` in a manual
6///     impl;
7///
8///   - a `fn next` "method" on it. There is actually a certain level of
9///     flexibility gained from this being a closure rather than a stateless
10///     associated function.
11///
12///     For instance, non-lent state (such as an internal mutable counter) can
13///     be implicity captured by such a closure, without having to funnel it
14///     through the lendable `State`.
15///
16/// ## Example
17///
18/**  - ```rust
19    use ::lending_iterator::prelude::*;
20
21    struct Person {
22        name: String,
23        age: u8,
24    }
25
26    fn example (person: &mut Person)
27      -> impl '_ + LendingIterator
28    /* or:
29      -> impl '_ + LendingIteratorDyn<Item = HKT!(&str)>
30     */
31    {
32        lending_iterator::from_fn::<HKT!(&str), _, _>(
33            person,
34            |p| if p.age > 0 {
35                Some(&p.name)
36            } else {
37                None
38            },
39        )
40    }
41    ``` */
42///
43/// ## Remarks
44///
45/// It can also be viewed as a convenience layer over:
46///
47/// <code>::lending_iterator::[repeat_mut]\(state\)<br/>    [.filter_map]::\<Item, _\>\(move |\[\], it| next\(it\)\)</code>
48///
49/**  - ```rust
50    use ::lending_iterator::prelude::*;
51
52    struct Person {
53        name: String,
54        age: u8,
55    }
56
57    fn example (person: &mut Person)
58      -> impl '_ + LendingIterator
59    /* or:
60      -> impl '_ + LendingIteratorDyn<Item = HKT!(&str)>
61     */
62    {
63        lending_iterator::repeat_mut(person)
64            .filter_map::<HKT!(&str), _>(
65                |[], p| if p.age > 0 {
66                    Some(&p.name)
67                } else {
68                    None
69                },
70            )
71    }
72    ``` */
73///
74/// [repeat_mut]: crate::repeat_mut()
75/// [.filter_map]: crate::LendingIterator::filter_map
76///
77/// ### `FromFn`
78///
79/// The returned `struct` —[`FromFn`]— can also be used directly, to benefit
80/// from "named arguments", at the cost of having to provide a `PhantomData`
81/// parameter.
82pub
83fn from_fn<Item, State, Next> (
84    state: State,
85    next: Next,
86) -> FromFn<Item, State, Next>
87where
88    Item : HKT,
89    Next : FnMut(&'_ mut State) -> Option< A!(Item<'_>) >,
90{
91    FromFn { state, next, _phantom: <_>::default() }
92}
93
94/// The <code>impl [LendingIterator]</code> returned by [`from_fn()`].
95///
96/// ## Example
97///
98/**  - ```rust
99    use ::lending_iterator::prelude::*;
100
101    struct Person {
102        name: String,
103        age: u8,
104    }
105
106    fn example (person: &mut Person)
107      -> impl '_ + LendingIterator
108    /* or:
109      -> impl '_ + LendingIteratorDyn<Item = HKT!(&str)>
110     */
111    {
112        lending_iterator::FromFn::<HKT!(&str), _, _> {
113            state: person,
114            next: |p| if p.age > 0 {
115                Some(&p.name)
116            } else {
117                None
118            },
119            _phantom: <_>::default(),
120        }
121    }
122    ``` */
123pub
124struct FromFn<Item, State, Next>
125where
126    Item : HKT,
127    Next : FnMut(&'_ mut State) -> Option< A!(Item<'_>) >,
128{
129    /// The state owned by this [`LendingIterator`].
130    ///
131    ///  - Think of `Self` within a manual implementation of the trait;
132    ///
133    ///  - Think of [`repeat_mut()`].
134    pub
135    state: State,
136
137    /// The "`fn next()`" of a "manual implementation of the trait".
138    ///
139    /// Trick: since it's only required to be a closure, this `Next` closure
140    /// can capture state on its own, provided it does not need to lend from it.
141    ///
142    /// This can lead to slightly more lightweight `FromFn` / `from_fn` calls:
143    ///   - put the lent / borrowed state inside `.state`,
144    ///   - let the rest of the state be implicitly `move`-captured by this closure.
145    pub
146    next: Next,
147
148    /// The signature of `fn next` in a `PhantomData`.
149    pub
150    _phantom: PhantomData<
151        fn(&mut State) -> Option<A!(Item<'_>)>,
152    >,
153}
154
155#[gat]
156impl<Item, State, Next>
157    LendingIterator
158for
159    FromFn<Item, State, Next>
160where
161    Item : HKT,
162    Next : FnMut(&'_ mut State) -> Option< A!(Item<'_>) >,
163{
164    type Item<'next>
165    where
166        Self : 'next,
167    =
168        A!(Item<'next>)
169    ;
170
171    fn next (self: &'_ mut FromFn<Item, State, Next>)
172      -> Option< A!(Item<'_>) >
173    {
174        let Self { state, next, .. } = self;
175        next(state)
176    }
177}