Skip to content

Commit 2baf60d

Browse files
committed
follow [rename Generator to Coroutine](rust-lang/rust#116958) and fix #10
1 parent b6fd587 commit 2baf60d

File tree

6 files changed

+82
-63
lines changed

6 files changed

+82
-63
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# version 0.4.0
2+
* follow [rename Generator to Coroutine](https://github.com/rust-lang/rust/pull/116958) and fix #10
3+
14
# version 0.3
25
* made the crate no_std compatible (#5)
36
* added struct GenIterReturn and macro gen_iter_return! to iterate over a generator and get the return value (#6)

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
[package]
22
name = "gen-iter"
3-
version = "0.2.1"
3+
version = "0.4.0"
4+
edition = "2021"
45
authors = ["tinaun <tinagma@gmail.com>"]
5-
keywords = ["generator", "iterator"]
6-
description = "temporary util for creating iterators using generators"
6+
keywords = ["coroutine", "generator", "iterator"]
7+
description = "temporary util for creating iterators using coroutines"
78

89
documentation = "https://docs.rs/gen-iter"
910
repository = "https://github.com/tinaun/gen-iter"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# gen_iter - iterators using generators.
1+
# gen_iter - iterators using coroutines/generators.
22

33
see [the docs](https://docs.rs/gen-iter) for examples and usage.
44

src/gen_iter.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
use core::ops::{Generator, GeneratorState};
21
use core::iter::Iterator;
32
use core::marker::Unpin;
3+
use core::ops::{Coroutine, CoroutineState};
44
use core::pin::Pin;
55

6-
/// an iterator that holds an internal generator representing
6+
/// an iterator that holds an internal coroutine representing
77
/// the iteration state
88
#[derive(Copy, Clone, Debug)]
99
pub struct GenIter<T>(pub T)
1010
where
11-
T: Generator<Return = ()> + Unpin;
11+
T: Coroutine<Return = ()> + Unpin;
1212

1313
impl<T> Iterator for GenIter<T>
1414
where
15-
T: Generator<Return = ()> + Unpin,
15+
T: Coroutine<Return = ()> + Unpin,
1616
{
1717
type Item = T::Yield;
1818

1919
#[inline]
2020
fn next(&mut self) -> Option<Self::Item> {
2121
match Pin::new(&mut self.0).resume(()) {
22-
GeneratorState::Yielded(n) => Some(n),
23-
GeneratorState::Complete(()) => None,
22+
CoroutineState::Yielded(n) => Some(n),
23+
CoroutineState::Complete(()) => None,
2424
}
2525
}
2626
}
2727

2828
impl<G> From<G> for GenIter<G>
2929
where
30-
G: Generator<Return = ()> + Unpin,
30+
G: Coroutine<Return = ()> + Unpin,
3131
{
3232
#[inline]
3333
fn from(gen: G) -> Self {
@@ -36,10 +36,10 @@ where
3636
}
3737

3838

39-
/// macro to simplify iterator - via - generator construction
39+
/// macro to simplify iterator - via - coroutine construction
4040
///
4141
/// ```
42-
/// #![feature(generators)]
42+
/// #![feature(coroutines)]
4343
///
4444
/// use gen_iter::gen_iter;
4545
///
@@ -56,10 +56,10 @@ where
5656
#[macro_export]
5757
macro_rules! gen_iter {
5858
($block: block) => {
59-
$crate::GenIter(|| $block)
59+
$crate::GenIter(#[coroutine] || $block)
6060
};
6161
(move $block: block) => {
62-
$crate::GenIter(move || $block)
62+
$crate::GenIter(#[coroutine] move || $block)
6363
}
6464
}
6565

@@ -82,10 +82,13 @@ mod tests {
8282

8383
#[test]
8484
fn into_gen_iter() {
85-
let mut g: GenIter<_> = (|| {
86-
yield 1;
87-
yield 2;
88-
}).into();
85+
let mut g: GenIter<_> = (
86+
#[coroutine]
87+
|| {
88+
yield 1;
89+
yield 2;
90+
}
91+
).into();
8992

9093
assert_eq!(g.next(), Some(1));
9194
assert_eq!(g.next(), Some(2));

src/gen_iter_return.rs

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
use core::ops::{Generator, GeneratorState};
2-
use core::iter::{Iterator, FusedIterator};
1+
use core::iter::{FusedIterator, Iterator};
32
use core::marker::Unpin;
3+
use core::ops::{Coroutine, CoroutineState};
44
use core::pin::Pin;
55

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`,
77
/// `&mut GenIterReturn<G>` acts as an iterator.
8-
///
8+
///
99
/// 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
1212
/// 3. maybe less efficient than `GenIter<G>`
1313
#[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>);
1515

16-
impl<G: Generator + Unpin> GenIterReturn<G> {
16+
impl<G: Coroutine + Unpin> GenIterReturn<G> {
1717
#[inline]
1818
pub fn new(g: G) -> Self {
1919
GenIterReturn(Err(g))
@@ -37,43 +37,43 @@ impl<G: Generator + Unpin> GenIterReturn<G> {
3737
/// in which return value cannot be got.
3838
/// ```compile_fail
3939
/// // !!INVALID CODE!!
40-
/// # #![feature(generators)]
40+
/// # #![feature(coroutines)]
4141
/// # use gen_iter::gen_iter_return;
4242
/// let mut g = gen_iter_return!({ yield 1; return "done"; });
4343
/// for v in g {} // invalid, because `GenIterReturn<G>` is not `Iterator`
4444
/// let ret = g.return_or_self(); // g is dropped after for loop
4545
/// ```
46-
impl<G: Generator + Unpin> Iterator for &mut GenIterReturn<G> {
46+
impl<G: Coroutine + Unpin> Iterator for &mut GenIterReturn<G> {
4747
type Item = G::Yield;
4848

4949
#[inline]
5050
fn next(&mut self) -> Option<Self::Item> {
5151
match self.0 {
5252
Ok(_) => None,
5353
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) => {
5656
self.0 = Ok(r);
5757
None
5858
},
59-
}
59+
},
6060
}
6161
}
6262
}
6363

6464
/// `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> {}
6666

67-
impl<G: Generator + Unpin> From<G> for GenIterReturn<G> {
67+
impl<G: Coroutine + Unpin> From<G> for GenIterReturn<G> {
6868
#[inline]
6969
fn from(g: G) -> Self {
7070
GenIterReturn::new(g)
7171
}
7272
}
7373

74-
/// macro to simplify iterator - via - generator with return value construction
74+
/// macro to simplify iterator - via - coroutine with return value construction
7575
/// ```
76-
/// #![feature(generators)]
76+
/// #![feature(coroutines)]
7777
///
7878
/// use gen_iter::gen_iter_return;
7979
///
@@ -84,18 +84,18 @@ impl<G: Generator + Unpin> From<G> for GenIterReturn<G> {
8484
/// });
8585
///
8686
/// 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
8888
/// 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
9090
/// ```
9191
#[macro_export]
9292
macro_rules! gen_iter_return {
9393
($block: block) => {
94-
$crate::GenIterReturn::new(|| $block)
94+
$crate::GenIterReturn::new(#[coroutine] || $block)
9595
};
9696
(move $block: block) => {
97-
$crate::GenIterReturn::new(move || $block)
98-
}
97+
$crate::GenIterReturn::new(#[coroutine] move || $block)
98+
};
9999
}
100100

101101
#[cfg(test)]
@@ -106,17 +106,20 @@ mod tests {
106106
/// and show that it won't panic when call `next()` even exhausted.
107107
#[test]
108108
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+
);
113116

114117
assert_eq!((&mut g).next(), Some(1));
115118
assert_eq!(g.is_done(), false);
116119

117120
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,
120123
};
121124

122125
assert_eq!((&mut g).next(), None);
@@ -128,11 +131,14 @@ mod tests {
128131
}
129132

130133
#[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+
);
136142

137143
assert_eq!((&mut g).next(), Some(1));
138144
assert_eq!((&mut g).next(), None);

src/lib.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1-
//! # gen_iter - create generators to use as iterators
2-
//!
1+
//! # gen_iter - create coroutines to use as iterators
2+
//!
3+
//! **Important: [rename Generator to Coroutine](https://github.com/rust-lang/rust/pull/116958)**
4+
//!
5+
//! ## Prerequirements
6+
//! Nightly rust toolchain of edition 2021 after 2023-10-21.
7+
//!
38
//! ## [`GenIter`] and [`gen_iter!`]
4-
//! [`GenIter`] converts a [`Generator<(), Return=()>`](core::ops::Generator) into an iterator over the
5-
//! yielded type of the generator. The return type of the generator needs to be `()`.
9+
//! [`GenIter`] converts a [`Coroutine<(), Return=()>`](core::ops::Coroutine) into an iterator over the
10+
//! yielded type of the coroutine. The return type of the coroutine needs to be `()`.
611
//!
712
//! [`gen_iter!`] helps to create a [`GenIter`]
813
//!
914
//! ```
10-
//! #![feature(generators)]
15+
//! #![feature(coroutines)]
1116
//!
1217
//! use gen_iter::gen_iter;
1318
//!
@@ -32,14 +37,14 @@
3237
//! ```
3338
//!
3439
//! ## [`GenIterReturn`] and [`gen_iter_return!`]
35-
//! [`GenIterReturn`] can be converted from a [`Generator<()>`](core::ops::Generator),
40+
//! [`GenIterReturn`] can be converted from a [`Coroutine<()>`](core::ops::Coroutine),
3641
//! `&mut GenIterReturn<G>` can be used as iterator.
37-
//! The return value of the generator can be got after the iterator is exhausted.
42+
//! The return value of the coroutine can be got after the iterator is exhausted.
3843
//!
3944
//! [`gen_iter_return!`] helps to create a [`GenIterReturn`].
4045
//!
4146
//! ```
42-
//! #![feature(generators)]
47+
//! #![feature(coroutines)]
4348
//!
4449
//! use gen_iter::gen_iter_return;
4550
//!
@@ -52,12 +57,13 @@
5257
//! for y in &mut g {
5358
//! println!("yield {}", y);
5459
//! }
55-
//! println!("generator is_done={}", g.is_done()); // true
56-
//! println!("generator returns {}", g.return_or_self().ok().unwrap()); // "done"
60+
//! println!("coroutine is_done={}", g.is_done()); // true
61+
//! println!("coroutine returns {}", g.return_or_self().ok().unwrap()); // "done"
5762
//! ```
5863
5964
#![no_std]
60-
#![feature(generators, generator_trait)]
65+
#![feature(coroutines, coroutine_trait)]
66+
#![feature(stmt_expr_attributes)]
6167

6268
mod gen_iter;
6369
pub use gen_iter::*;

0 commit comments

Comments
 (0)