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}