Skip to content

Instantly share code, notes, and snippets.

@vxgmichel
Last active October 12, 2019 16:11
Show Gist options
  • Save vxgmichel/45ddea42c6965927761e51d3f0a1213b to your computer and use it in GitHub Desktop.
Save vxgmichel/45ddea42c6965927761e51d3f0a1213b to your computer and use it in GitHub Desktop.
Recursive generators in rust
#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
use std::pin::Pin;
// Generator to Iterator
struct GeneratorToIterator<G>(G);
impl<G> Iterator for GeneratorToIterator<G>
where
G: Generator<Return = ()>,
{
type Item = G::Yield;
fn next(&mut self) -> Option<Self::Item> {
let me = unsafe { Pin::new_unchecked(&mut self.0) };
match me.resume() {
GeneratorState::Yielded(x) => Some(x),
GeneratorState::Complete(_) => None,
}
}
}
// Recursive generator
fn recursive_generator() -> impl Iterator<Item = u64> {
GeneratorToIterator(move || {
// Yield a few values
yield 1;
yield 2;
yield 3;
// Initialize the inner generator
let mut inner_value: u64 = 0;
let mut inner_generator: Box<dyn Iterator<Item = u64>>;
inner_generator = Box::new(recursive_generator());
// Get the first value of the inner generator
match inner_generator.next(){
Some(x) => inner_value = x,
None => {},
}
// Yield some other values
yield inner_value;
})
}
// Main
fn main() {
for x in recursive_generator() {
println!("{}", x)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment