genawaiter/stack/
iterator.rs1use crate::{ops::GeneratorState, stack::generator::Gen};
2use std::future::Future;
3
4impl<'s, Y, F: Future<Output = ()>> IntoIterator for Gen<'s, Y, (), F> {
5 type Item = Y;
6 type IntoIter = IntoIter<'s, Y, F>;
7
8 #[must_use]
9 fn into_iter(self) -> Self::IntoIter {
10 IntoIter { generator: self }
11 }
12}
13
14pub struct IntoIter<'s, Y, F: Future<Output = ()>> {
15 generator: Gen<'s, Y, (), F>,
16}
17
18impl<'s, Y, F: Future<Output = ()>> Iterator for IntoIter<'s, Y, F> {
19 type Item = Y;
20
21 fn next(&mut self) -> Option<Self::Item> {
22 match self.generator.resume() {
23 GeneratorState::Yielded(x) => Some(x),
24 GeneratorState::Complete(()) => None,
25 }
26 }
27}
28
29impl<'r, 's, Y, F: Future<Output = ()>> IntoIterator for &'r mut Gen<'s, Y, (), F> {
30 type Item = Y;
31 type IntoIter = MutIntoIter<'r, 's, Y, F>;
32
33 fn into_iter(self) -> Self::IntoIter {
34 MutIntoIter { generator: self }
35 }
36}
37
38pub struct MutIntoIter<'r, 's, Y, F: Future<Output = ()>> {
39 generator: &'r mut Gen<'s, Y, (), F>,
40}
41
42impl<'r, 's, Y, F: Future<Output = ()>> Iterator for MutIntoIter<'r, 's, Y, F> {
43 type Item = Y;
44
45 fn next(&mut self) -> Option<Self::Item> {
46 match self.generator.resume() {
47 GeneratorState::Yielded(x) => Some(x),
48 GeneratorState::Complete(()) => None,
49 }
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use crate::stack::{let_gen_using, Co, Gen, Shelf};
56 use std::iter::IntoIterator;
57
58 async fn produce(co: Co<'_, i32>) {
59 co.yield_(10).await;
60 co.yield_(20).await;
61 }
62
63 #[test]
64 fn let_gen_using_into_iter() {
65 let_gen_using!(gen, produce);
66
67 let items: Vec<_> = gen.into_iter().collect();
68 assert_eq!(items, [10, 20]);
69 }
70
71 #[test]
72 fn let_gen_using_for_loop() {
73 let_gen_using!(gen, produce);
74
75 let mut sum = 0;
76 for x in gen {
77 sum += x;
78 }
79 assert_eq!(sum, 30);
80 }
81
82 #[test]
83 fn shelf_generator_into_iter() {
84 let mut shelf = Shelf::new();
85 let gen = unsafe { Gen::new(&mut shelf, produce) };
86
87 let items: Vec<_> = gen.into_iter().collect();
88 assert_eq!(items, [10, 20]);
89 }
90
91 #[test]
92 fn shelf_generator_for_loop() {
93 let mut shelf = Shelf::new();
94 let gen = unsafe { Gen::new(&mut shelf, produce) };
95
96 let mut sum = 0;
97 for x in gen {
98 sum += x;
99 }
100 assert_eq!(sum, 30);
101 }
102}