1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use core::{
marker::Unpin,
ops::{Generator, GeneratorState},
pin::Pin,
};
pub struct SimpleGenIterator<G>(pub(crate) G);
pub trait SupportedReturnValue {}
impl SupportedReturnValue for () {}
impl SupportedReturnValue for ! {}
impl<G> Iterator for SimpleGenIterator<G>
where
G: Generator<()> + Unpin,
G::Return: SupportedReturnValue,
{
type Item = G::Yield;
fn next(&mut self) -> Option<Self::Item> {
match Pin::new(&mut self.0).resume(()) {
GeneratorState::Yielded(y) => Some(y),
GeneratorState::Complete(_) => None,
}
}
}
pub struct RawGenIterator<G> {
pub(crate) gen: G,
}
impl<G> Iterator for RawGenIterator<G>
where
G: Generator<()> + Unpin,
{
type Item = GeneratorState<G::Yield, G::Return>;
fn next(&mut self) -> Option<Self::Item> {
Some(Pin::new(&mut self.gen).resume(()))
}
}
pub enum FusedGenIterator<G: Generator<()>> {
Generator(G),
Completed(G::Return),
}
impl<G: Generator<()> + Unpin> FusedGenIterator<G> {
pub(crate) fn new(g: G) -> Self {
FusedGenIterator::Generator(g)
}
pub fn is_completed(&self) -> bool {
matches!(self, FusedGenIterator::Generator(_))
}
#[track_caller]
pub fn into_return(self) -> G::Return {
match self {
FusedGenIterator::Completed(c) => c,
FusedGenIterator::Generator(_) => {
panic!("into_return called, but generator has not completed yat")
}
}
}
}
impl<G: Generator<()> + Unpin> Iterator for FusedGenIterator<G> {
type Item = G::Yield;
fn next(&mut self) -> Option<Self::Item> {
let gen = match self {
FusedGenIterator::Generator(gen) => Pin::new(gen),
FusedGenIterator::Completed(_) => return None,
};
match gen.resume(()) {
GeneratorState::Yielded(y) => Some(y),
GeneratorState::Complete(c) => {
*self = FusedGenIterator::Completed(c);
None
}
}
}
}
impl<G: Generator<()> + Unpin> core::iter::FusedIterator for FusedGenIterator<G> {}