@@ -32,6 +32,15 @@ impl<G: Generator + Unpin> GenIterReturn<G> {
32
32
}
33
33
}
34
34
35
+ /// Force use `&mut g` as iterator to prevent the code below,
36
+ /// in which return value cannot be got.
37
+ /// ```compile_fail
38
+ /// # #![feature(generators)]
39
+ /// # use gen_iter::gen_iter_return;
40
+ /// let mut g = gen_iter_return!({ yield 1; return "done"; }
41
+ /// for v in g {} // invalid, because `GenIterReturn<G>` is not `Iterator`
42
+ /// let ret = g.return_or_self().unwrap(); // g is dropped after for
43
+ /// ```
35
44
impl < G : Generator + Unpin > Iterator for & mut GenIterReturn < G > {
36
45
type Item = G :: Yield ;
37
46
@@ -50,6 +59,7 @@ impl<G: Generator + Unpin> Iterator for &mut GenIterReturn<G> {
50
59
}
51
60
}
52
61
62
+ /// `GenIterReturn<G>` satisfies the trait `FusedIterator`
53
63
impl < G : Generator + Unpin > FusedIterator for & mut GenIterReturn < G > { }
54
64
55
65
impl < G : Generator + Unpin > From < G > for GenIterReturn < G > {
@@ -60,8 +70,6 @@ impl<G: Generator + Unpin> From<G> for GenIterReturn<G> {
60
70
}
61
71
62
72
/// macro to simplify iterator - via - generator with return value construction
63
- ///
64
- /// Examples:
65
73
/// ```
66
74
/// #![feature(generators)]
67
75
///
@@ -78,19 +86,6 @@ impl<G: Generator + Unpin> From<G> for GenIterReturn<G> {
78
86
/// assert_eq!((&mut g).next(), None); // safe to call `next()` after done
79
87
/// assert_eq!(g.return_or_self().ok(), Some("done")); // get return value of generator
80
88
/// ```
81
- /// We should use `&mut g` in `for` statement, to keep `g` be valid after `for`, so we can get the return value.
82
- /// ```compile_fail
83
- /// #![feature(generators)]
84
- ///
85
- /// use gen_iter::gen_iter_return;
86
- ///
87
- /// let mut g = gen_iter_return!({
88
- /// yield 1;
89
- /// yield 2;
90
- /// return "done";
91
- /// });
92
- /// for v in g {} // compile failed, should use `&mut g`
93
- /// ```
94
89
#[ macro_export]
95
90
macro_rules! gen_iter_return {
96
91
( $block: block) => {
@@ -105,57 +100,55 @@ macro_rules! gen_iter_return {
105
100
mod tests {
106
101
use super :: GenIterReturn ;
107
102
103
+ /// test `new` and all instance method,
104
+ /// and show that it won't panic when call `next()` even exhausted.
108
105
#[ test]
109
106
fn it_works ( ) {
110
- let mut g = gen_iter_return ! ( {
107
+ let mut g = GenIterReturn :: new ( || {
111
108
yield 1 ;
112
- yield 2 ;
113
109
return "done" ;
114
110
} ) ;
115
111
116
112
assert_eq ! ( ( & mut g) . next( ) , Some ( 1 ) ) ;
117
113
assert_eq ! ( g. is_done( ) , false ) ;
118
- assert_eq ! ( ( & mut g) . next( ) , Some ( 2 ) ) ;
119
- assert_eq ! ( g. is_done( ) , false ) ;
114
+
120
115
assert_eq ! ( ( & mut g) . next( ) , None ) ;
121
116
assert_eq ! ( g. is_done( ) , true ) ;
122
- assert_eq ! ( ( & mut g) . next( ) , None ) ;
117
+
118
+ assert_eq ! ( ( & mut g) . next( ) , None ) ; // it won't panic when call `next()` even exhausted.
119
+
123
120
assert_eq ! ( g. return_or_self( ) . ok( ) , Some ( "done" ) ) ;
124
121
}
125
122
126
123
#[ test]
127
- fn gen_iter_return_from ( ) {
124
+ fn test_from ( ) {
128
125
let mut g: GenIterReturn < _ > = GenIterReturn :: from ( || {
129
126
yield 1 ;
130
- yield 2 ;
131
127
return "done" ;
132
128
} ) ;
133
- let mut gi = & mut g;
134
129
135
- assert_eq ! ( gi. next( ) , Some ( 1 ) ) ;
136
- assert_eq ! ( gi. next( ) , Some ( 2 ) ) ;
137
- assert_eq ! ( gi. next( ) , None ) ;
130
+ assert_eq ! ( ( & mut g) . next( ) , Some ( 1 ) ) ;
131
+ assert_eq ! ( ( & mut g) . next( ) , None ) ;
138
132
139
133
assert_eq ! ( g. is_done( ) , true ) ;
140
134
assert_eq ! ( g. return_or_self( ) . ok( ) , Some ( "done" ) ) ;
141
135
}
142
136
137
+ /// normal usage using macro `gen_iter_return`
143
138
#[ test]
144
- fn gen_iter_return_macro ( ) {
139
+ fn test_macro ( ) {
145
140
let mut g = gen_iter_return ! ( {
146
141
yield 1 ;
147
142
yield 2 ;
148
143
return "done" ;
149
144
} ) ;
150
145
151
- let mut sum = 0 ;
152
- let mut count = 0 ;
146
+ let ( mut sum, mut count) = ( 0 , 0 ) ;
153
147
for y in & mut g {
154
148
sum += y;
155
149
count += 1 ;
156
150
}
157
- assert_eq ! ( sum, 3 ) ;
158
- assert_eq ! ( count, 2 ) ;
151
+ assert_eq ! ( ( sum, count) , ( 3 , 2 ) ) ;
159
152
160
153
assert_eq ! ( g. is_done( ) , true ) ;
161
154
assert_eq ! ( g. return_or_self( ) . ok( ) , Some ( "done" ) ) ;
0 commit comments