Remit

Rust generators implemented through async/await syntax.
The pinned implementation is stack-based, and the boxed is heap-based.
No fancy macros and a simple API. Values can be lazily or eagerly yielded.
No dependencies outside of std
.
Usage
Add to dependencies:
toml
[dependencies]
remit = "0.1.1"
Example code:
```rust
use std::pin::pin;
use remit::{Generator, Remit};
async fn gen(remit: Remit<', usize>) {
remit.value(42).await;
// Does not need to be limited
for i in 1.. {
remit.value(i).await
}
}
for item in pin!(Generator::new()).of(gen).take(10) {
println!("{item}");
// Prints 42, 1, 2, 3, 4, 5, 6, 7, 8, 9
}
asserteq!(vec![42, 1, 2, 3], pin!(Generator::new()).of(gen).take(4).collect::>());
/* // Rust has trouble determining the lifetime
asserteq!(
vec![1],
pin!(Generator::new())
.of(|remit: Remit<', usize>| async move { remit.value(1).await; })
.collect::>(),
);
*/
asserteq!(vec![42, 1], Generator::boxed(gen).take(2).collect::>());
asserteq!(vec![1], Generator::boxed(|remit| async move { remit.value(1).await; }).collect::>());
fn iter() -> impl Iterator- {
Generator::boxed(gen)
}
async fn scream(iter: impl Iterator- , remit: Remit<', String>) {
for person in iter {
remit.value(format!("{person} scream!")).await
}
remit.value("... for ice cream!".tostring());
}
let expected: Vec = ["You scream!", "I scream!", "We all scream!", "... for ice cream!"].iter().map(ToString::tostring).collect();
asserteq!(
expected,
pin!(Generator::new()).parameterized(scream, ["You", "I", "We all"].iter()).collect::>(),
);
assert_eq!(
expected,
Generator::boxed(|remit| scream(["You", "I", "We all"].iter(), remit)).collect::>(),
);
```
License
MIT or APACHE-2, at your option.
See respective LICENSE files.