1use crate::core::hint::unreachable_unchecked;
2
3use crate::core::ptr::NonNull;
4
5use crate::core::marker::{PhantomData, PhantomPinned};
6
7use crate::core::convert::Infallible;
8
9use crate::core::pin::Pin;
10
11use crate::fn_trait::FnOnceOutput;
12use crate::{Generator, GeneratorState};
13
14pub struct Iter<G>(G);
15
16impl<G> Iterator for Iter<G>
17where
18 G: Generator<(), Return = ()> + Unpin,
19{
20 type Item = G::Yield;
21
22 fn next(&mut self) -> Option<Self::Item> {
23 loop {
24 match Pin::new(&mut self.0).resume(()) {
25 GeneratorState::Complete(_) => return None,
26 GeneratorState::Suspend => continue,
27 GeneratorState::Yield(val) => return Some(val),
28 }
29 }
30 }
31}
32
33pub fn from_iter<Item>(
34 iter: impl IntoIterator<Item = Item>,
35) -> impl Generator<Yield = Item, Return = ()> {
36 struct GenIter<I: Iterator>(I);
37 impl<I: Iterator> Generator for GenIter<I> {
38 type Return = ();
39 type Yield = I::Item;
40 fn resume(self: Pin<&mut Self>, _value: ()) -> GeneratorState<Self::Yield, Self::Return> {
41 match unsafe { self.get_unchecked_mut() }.0.next() {
43 Some(val) => GeneratorState::Yield(val),
44 None => GeneratorState::Complete(()),
45 }
46 }
47 }
48 GenIter(iter.into_iter())
49}
50
51pub const fn from_fn<Resume, Yield, Return>(
52 f: impl FnMut(Resume) -> GeneratorState<Yield, Return>,
53) -> impl Generator<Resume, Yield = Yield, Return = Return> {
54 struct GenFn<F>(F);
55 impl<F, R, Y, Out> Generator<R> for GenFn<F>
56 where
57 F: FnMut(R) -> GeneratorState<Y, Out>,
58 {
59 type Return = Out;
60 type Yield = Y;
61 fn resume(self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
62 unsafe { self.get_unchecked_mut() }.0(value)
64 }
65 }
66 GenFn(f)
67}
68
69pub trait GeneratorIterator {
70 type Item;
71 type Iter: Iterator<Item = Self::Item>;
72 fn into_iter(self) -> Self::Iter;
73}
74
75impl<G> GeneratorIterator for G
76where
77 G: Generator<(), Return = ()> + Unpin,
78{
79 type Item = G::Yield;
80 type Iter = Iter<G>;
81 fn into_iter(self) -> Self::Iter {
82 Iter(self)
83 }
84}
85
86pub use either::Either;
87
88pub trait GeneratorExt<R>: Generator<R> {
89 fn receiving<F, U>(self, f: F) -> Receiving<Self, F>
90 where
91 Self: Sized,
92 F: FnMut(U) -> R,
93 {
94 Receiving { g: self, f }
95 }
96
97 fn compose<G: Generator<Self::Yield>>(self, then: G) -> Compose<Self, G>
98 where
99 Self: Sized,
100 {
101 Compose {
102 first: self,
103 second: then,
104 }
105 }
106
107 fn map_complete<U, F>(self, f: F) -> MapComplete<Self, F>
108 where
109 Self: Sized,
110 F: FnOnce(Self::Return) -> U,
111 {
112 MapComplete {
113 generator: self,
114 f: Some(f),
115 }
116 }
117
118 fn map_yield<U, F>(self, f: F) -> MapYield<Self, F>
119 where
120 Self: Sized,
121 F: FnMut(Self::Yield) -> U,
122 {
123 MapYield { generator: self, f }
124 }
125
126 fn and_then<G, F>(self, f: F) -> AndThen<Self, F, G>
127 where
128 Self: Sized,
129 G: Generator<R, Yield = Self::Yield>,
130 F: FnOnce(Self::Return) -> G,
131 {
132 AndThen::Before {
133 g: self,
134 f: Some(f),
135 }
136 }
137
138 fn flatten(self) -> Flatten<Self, Self::Yield>
139 where
140 Self: Sized,
141 Self::Yield: Generator<R, Return = ()>,
142 {
143 Flatten {
144 g: self,
145 current: None,
146 }
147 }
148}
149
150impl<G, R> GeneratorExt<R> for G where G: Generator<R> {}
151
152pub struct Compose<A, B> {
153 first: A,
154 second: B,
155}
156
157impl<A, B, R> Generator<R> for Compose<A, B>
158where
159 A: Generator<R>,
160 B: Generator<A::Yield>,
161{
162 type Return = Either<A::Return, B::Return>;
163 type Yield = B::Yield;
164
165 fn resume(mut self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
166 let first = unsafe { self.as_mut().map_unchecked_mut(|this| &mut this.first) };
167 let value = match first.resume(value) {
168 GeneratorState::Suspend => return GeneratorState::Suspend,
169 GeneratorState::Complete(x) => return GeneratorState::Complete(Either::Left(x)),
170 GeneratorState::Yield(value) => value,
171 };
172 let second = unsafe { self.map_unchecked_mut(|this| &mut this.second) };
173 second.resume(value).map_complete(Either::Right)
174 }
175}
176
177pub struct MapComplete<G, F> {
178 generator: G,
179 f: Option<F>,
180}
181
182pub struct MapYield<G, F> {
183 generator: G,
184 f: F,
185}
186
187impl<G, F, R, U> Generator<R> for MapComplete<G, F>
188where
189 G: Generator<R>,
190 F: FnOnce(G::Return) -> U,
191{
192 type Yield = G::Yield;
193 type Return = U;
194
195 fn resume(mut self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
196 let g = unsafe { self.as_mut().map_unchecked_mut(|this| &mut this.generator) };
197 g.resume(value)
198 .map_complete(|r| unsafe { self.get_unchecked_mut() }.f.take().unwrap()(r))
199 }
200}
201
202impl<G, F, R, U> Generator<R> for MapYield<G, F>
203where
204 G: Generator<R>,
205 F: FnMut(G::Yield) -> U,
206{
207 type Yield = U;
208 type Return = G::Return;
209
210 fn resume(self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
211 let this = unsafe { self.get_unchecked_mut() };
213 let g = unsafe { Pin::new_unchecked(&mut this.generator) };
214 g.resume(value).map_yield(&mut this.f)
215 }
216}
217
218pub enum AndThen<G1, F, G2> {
219 Before { g: G1, f: Option<F> },
220 After { g: G2 },
221}
222
223impl<G1, F, G2, R> Generator<R> for AndThen<G1, F, G2>
224where
225 G1: Generator<R>,
226 F: FnOnce(G1::Return) -> G2,
227 G2: Generator<R, Yield = G1::Yield>,
228{
229 type Yield = G1::Yield;
230 type Return = G2::Return;
231
232 fn resume(mut self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
233 let this = unsafe { self.as_mut().get_unchecked_mut() };
234
235 match this {
236 AndThen::Before { g, f } => match unsafe { Pin::new_unchecked(g) }.resume(value) {
237 GeneratorState::Complete(r) => {
238 let f = f.take().unwrap();
239 let g = f(r);
240 *this = AndThen::After { g };
241 GeneratorState::Suspend
242 }
243 GeneratorState::Yield(y) => GeneratorState::Yield(y),
244 GeneratorState::Suspend => GeneratorState::Suspend,
245 },
246 AndThen::After { g } => unsafe { Pin::new_unchecked(g) }.resume(value),
247 }
248 }
249}
250
251pub struct Flatten<G, C> {
252 g: G,
253 current: Option<C>,
254}
255
256impl<R, G, C> Generator<R> for Flatten<G, C>
257where
258 G: Generator<R, Yield = C>,
259 C: Generator<R, Return = ()>,
260{
261 type Yield = C::Yield;
262 type Return = G::Return;
263
264 fn resume(self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
265 let this = unsafe { self.get_unchecked_mut() };
266
267 if let Some(current) = &mut this.current {
268 match unsafe { Pin::new_unchecked(current) }.resume(value) {
269 GeneratorState::Suspend => GeneratorState::Suspend,
270 GeneratorState::Complete(()) => {
271 this.current = None;
272 GeneratorState::Suspend
273 }
274 GeneratorState::Yield(y) => GeneratorState::Yield(y),
275 }
276 } else {
277 match unsafe { Pin::new_unchecked(&mut this.g) }.resume(value) {
278 GeneratorState::Complete(r) => GeneratorState::Complete(r),
279 GeneratorState::Yield(c) => {
280 this.current = Some(c);
281 GeneratorState::Suspend
282 }
283 GeneratorState::Suspend => GeneratorState::Suspend,
284 }
285 }
286 }
287}
288
289pub struct Once<Y>(Option<Y>);
290pub struct OnceWith<F>(Option<F>);
291
292pub struct CompleteWith<F, Y>(Option<F>, PhantomData<Y>);
293
294impl<Y> Generator for Once<Y> {
295 type Return = ();
296 type Yield = Y;
297 fn resume(self: Pin<&mut Self>, _value: ()) -> GeneratorState<Self::Yield, Self::Return> {
298 let this = unsafe { self.get_unchecked_mut() };
299 if let Some(y) = this.0.take() {
300 GeneratorState::Yield(y)
301 } else {
302 GeneratorState::Complete(())
303 }
304 }
305}
306
307impl<F, R, Y> Generator<R> for OnceWith<F>
308where
309 F: FnOnce(R) -> Y,
310{
311 type Return = ();
312 type Yield = Y;
313 fn resume(self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
314 let this = unsafe { self.get_unchecked_mut() };
315 if let Some(f) = this.0.take() {
316 GeneratorState::Yield(f(value))
317 } else {
318 GeneratorState::Complete(())
319 }
320 }
321}
322
323impl<F, R, C, Y> Generator<R> for CompleteWith<F, Y>
324where
325 F: FnOnce(R) -> C,
326{
327 type Return = C;
328 type Yield = Y;
329 fn resume(self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
330 let this = unsafe { self.get_unchecked_mut() };
331 let f = this.0.take().unwrap();
332 GeneratorState::Complete(f(value))
333 }
334}
335
336pub const fn identity<Y>() -> impl Generator<Y, Yield = Y, Return = Infallible> {
337 from_fn(GeneratorState::Yield)
338}
339
340pub const fn once<Y>(yielded: Y) -> impl Generator<Yield = Y, Return = ()> {
341 Once(Some(yielded))
342}
343pub const fn once_with<F, R, Y>(f: F) -> impl Generator<R, Yield = Y, Return = ()>
344where
345 F: FnOnce(R) -> Y,
346{
347 OnceWith(Some(f))
348}
349
350pub const fn complete_with<F, Y, R, C>(f: F) -> impl Generator<R, Yield = Y, Return = C>
351where
352 F: FnOnce(R) -> C,
353{
354 CompleteWith(Some(f), PhantomData)
355}
356
357pub struct Receiving<G, F> {
358 g: G,
359 f: F,
360}
361
362impl<R1, R2, G, F> Generator<R1> for Receiving<G, F>
363where
364 F: FnMut(R1) -> R2,
365 G: Generator<R2>,
366{
367 type Yield = G::Yield;
368 type Return = G::Return;
369
370 fn resume(self: Pin<&mut Self>, value: R1) -> GeneratorState<Self::Yield, Self::Return> {
371 let this = unsafe { self.get_unchecked_mut() };
372 let r2 = (this.f)(value);
373 unsafe { Pin::new_unchecked(&mut this.g) }.resume(r2)
374 }
375}
376
377enum Gen<F, G> {
378 Init(Option<F>),
379 Gen(G),
380}
381
382struct ContextGen<C, R, F>
383where
384 F: FnOnceOutput<NonNull<C>, Out: Generator<R>>,
385{
386 context: Option<C>,
387 g: Gen<F, <F as FnOnceOutput<NonNull<C>>>::Out>,
388 _pinned: PhantomPinned,
389 _resume: PhantomData<R>,
390}
391
392impl<C, R, F> Generator<R> for ContextGen<C, R, F>
393where
394 F: FnOnceOutput<NonNull<C>, Out: Generator<R, Return = ()>>,
395{
396 type Return = C;
397 type Yield = <<F as FnOnceOutput<NonNull<C>>>::Out as Generator<R>>::Yield;
398
399 fn resume(self: Pin<&mut Self>, value: R) -> GeneratorState<Self::Yield, Self::Return> {
400 let this = unsafe { self.get_unchecked_mut() };
401 if let Gen::Init(f) = &mut this.g {
402 let g = f
403 .take()
404 .unwrap()
405 .call(NonNull::from_mut(this.context.as_mut().unwrap()));
406 this.g = Gen::Gen(g);
407 };
408 let Gen::Gen(g) = &mut this.g else {
409 unsafe { unreachable_unchecked() };
410 };
411 unsafe { Pin::new_unchecked(g) }
412 .resume(value)
413 .map_complete(|_| this.context.take().unwrap())
414 }
415}
416
417pub const fn context<C, R, Yield>(
419 c: C,
420 f: impl for<'a> FnOnceOutput<&'a mut C, Out: Generator<R, Yield = Yield, Return = ()>>,
421) -> impl Generator<R, Yield = Yield, Return = C> {
422 ContextGen::<C, R, _> {
423 context: Some(c),
424 g: Gen::Init(Some(move |ptr: NonNull<C>| unsafe {
425 f.call(&mut *ptr.as_ptr())
426 })),
427 _pinned: PhantomPinned,
428 _resume: PhantomData,
429 }
430}