1
- use core::ops::{Generator, GeneratorState};
2
- use core::iter::{Iterator, FusedIterator};
1
+ use core::iter::{FusedIterator, Iterator};
3
2
use core::marker::Unpin;
3
+ use core::ops::{Coroutine, CoroutineState};
4
4
use core::pin::Pin;
5
5
6
- /// `GenIterReturn<G>` holds a generator `G` or the return value of `G`,
6
+ /// `GenIterReturn<G>` holds a coroutine `G` or the return value of `G`,
7
7
/// `&mut GenIterReturn<G>` acts as an iterator.
8
- ///
8
+ ///
9
9
/// Differences with `GenIter<G>`:
10
- /// 1. able to get return value of a generator
11
- /// 2. safe to call `next()` after generator is done without panic
10
+ /// 1. able to get return value of a coroutine
11
+ /// 2. safe to call `next()` after coroutine is done without panic
12
12
/// 3. maybe less efficient than `GenIter<G>`
13
13
#[derive(Copy, Clone, Debug)]
14
- pub struct GenIterReturn<G: Generator + Unpin>(Result<G::Return, G>);
14
+ pub struct GenIterReturn<G: Coroutine + Unpin>(Result<G::Return, G>);
15
15
16
- impl<G: Generator + Unpin> GenIterReturn<G> {
16
+ impl<G: Coroutine + Unpin> GenIterReturn<G> {
17
17
#[inline]
18
18
pub fn new(g: G) -> Self {
19
19
GenIterReturn(Err(g))
@@ -37,43 +37,43 @@ impl<G: Generator + Unpin> GenIterReturn<G> {
37
37
/// in which return value cannot be got.
38
38
/// ```compile_fail
39
39
/// // !!INVALID CODE!!
40
- /// # #![feature(generators )]
40
+ /// # #![feature(coroutines )]
41
41
/// # use gen_iter::gen_iter_return;
42
42
/// let mut g = gen_iter_return!({ yield 1; return "done"; });
43
43
/// for v in g {} // invalid, because `GenIterReturn<G>` is not `Iterator`
44
44
/// let ret = g.return_or_self(); // g is dropped after for loop
45
45
/// ```
46
- impl<G: Generator + Unpin> Iterator for &mut GenIterReturn<G> {
46
+ impl<G: Coroutine + Unpin> Iterator for &mut GenIterReturn<G> {
47
47
type Item = G::Yield;
48
48
49
49
#[inline]
50
50
fn next(&mut self) -> Option<Self::Item> {
51
51
match self.0 {
52
52
Ok(_) => None,
53
53
Err(ref mut g) => match Pin::new(g).resume(()) {
54
- GeneratorState ::Yielded(y) => Some(y),
55
- GeneratorState ::Complete(r) => {
54
+ CoroutineState ::Yielded(y) => Some(y),
55
+ CoroutineState ::Complete(r) => {
56
56
self.0 = Ok(r);
57
57
None
58
58
},
59
- }
59
+ },
60
60
}
61
61
}
62
62
}
63
63
64
64
/// `GenIterReturn<G>` satisfies the trait `FusedIterator`
65
- impl<G: Generator + Unpin> FusedIterator for &mut GenIterReturn<G> {}
65
+ impl<G: Coroutine + Unpin> FusedIterator for &mut GenIterReturn<G> {}
66
66
67
- impl<G: Generator + Unpin> From<G> for GenIterReturn<G> {
67
+ impl<G: Coroutine + Unpin> From<G> for GenIterReturn<G> {
68
68
#[inline]
69
69
fn from(g: G) -> Self {
70
70
GenIterReturn::new(g)
71
71
}
72
72
}
73
73
74
- /// macro to simplify iterator - via - generator with return value construction
74
+ /// macro to simplify iterator - via - coroutine with return value construction
75
75
/// ```
76
- /// #![feature(generators )]
76
+ /// #![feature(coroutines )]
77
77
///
78
78
/// use gen_iter::gen_iter_return;
79
79
///
@@ -84,18 +84,18 @@ impl<G: Generator + Unpin> From<G> for GenIterReturn<G> {
84
84
/// });
85
85
///
86
86
/// assert_eq!((&mut g).collect::<Vec<_>>(), [1, 2]); // use `&mut g` as an iterator
87
- /// assert_eq!(g.is_done(), true); // check whether generator is done
87
+ /// assert_eq!(g.is_done(), true); // check whether the coroutine is done
88
88
/// assert_eq!((&mut g).next(), None); // safe to call `next()` after done
89
- /// assert_eq!(g.return_or_self().ok(), Some("done")); // get return value of generator
89
+ /// assert_eq!(g.return_or_self().ok(), Some("done")); // get return value of the coroutine
90
90
/// ```
91
91
#[macro_export]
92
92
macro_rules! gen_iter_return {
93
93
($block: block) => {
94
- $crate::GenIterReturn::new(|| $block)
94
+ $crate::GenIterReturn::new(#[coroutine] || $block)
95
95
};
96
96
(move $block: block) => {
97
- $crate::GenIterReturn::new(move || $block)
98
- }
97
+ $crate::GenIterReturn::new(#[coroutine] move || $block)
98
+ };
99
99
}
100
100
101
101
#[cfg(test)]
@@ -106,17 +106,20 @@ mod tests {
106
106
/// and show that it won't panic when call `next()` even exhausted.
107
107
#[test]
108
108
fn it_works() {
109
- let mut g = GenIterReturn::new(|| {
110
- yield 1;
111
- return "done";
112
- });
109
+ let mut g = GenIterReturn::new(
110
+ #[coroutine]
111
+ || {
112
+ yield 1;
113
+ return "done";
114
+ },
115
+ );
113
116
114
117
assert_eq!((&mut g).next(), Some(1));
115
118
assert_eq!(g.is_done(), false);
116
119
117
120
g = match g.return_or_self() {
118
- Ok(_) => panic!("generator is done but should not"),
119
- Err(g) => g
121
+ Ok(_) => panic!("coroutine is done but should not"),
122
+ Err(g) => g,
120
123
};
121
124
122
125
assert_eq!((&mut g).next(), None);
@@ -128,11 +131,14 @@ mod tests {
128
131
}
129
132
130
133
#[test]
131
- fn from_generator() {
132
- let mut g = GenIterReturn::from(|| {
133
- yield 1;
134
- return "done";
135
- });
134
+ fn from_coroutine() {
135
+ let mut g = GenIterReturn::from(
136
+ #[coroutine]
137
+ || {
138
+ yield 1;
139
+ return "done";
140
+ },
141
+ );
136
142
137
143
assert_eq!((&mut g).next(), Some(1));
138
144
assert_eq!((&mut g).next(), None);
0 commit comments