[][src]Attribute Macro propane::generator

#[generator]

This macro can be applied to functions to make them into generators.

Functions annotated with this attribute use the yield keyword, instead of the return keyword. They yield an item and then continue. When you call a generator function, you get an iterator of the type it yields, rather than just one value of that type.

You can still use the return keyword to terminate the generator early, but the return keyword cannot take a value; it only terminates the function.

The behavior of ? is also modified in these functions. In the event of an error, the generator yields the error value, and then the next time it is resumed it returns None.

Forbidding self-references

Unlike async functions, generators cannot contain self-references: a reference into their stack space that exists across a yield point. Instead, anything you wish to have by reference you should move out of the state of the generator, taking it as an argument, or else not holding it by reference across a point that you yield.

Unstable features

In order to use this attribute, you must turn on all of these features:

  • generators
  • generator_trait
  • try_trait

Example

#![feature(generators, generator_trait, try_trait)]

#[propane::generator]
fn fizz_buzz() -> String {
   for x in 1..101 {
      match (x % 3 == 0, x % 5 == 0) {
          (true, true)  => yield String::from("FizzBuzz"),
          (true, false) => yield String::from("Fizz"),
          (false, true) => yield String::from("Buzz"),
          (..)          => yield x.to_string(),
      }
   }
}

fn main() {
    let mut fizz_buzz = fizz_buzz();
    assert_eq!(&fizz_buzz.next().unwrap()[..], "1");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "2");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "4");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Buzz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "7");

    // yada yada yada
    let mut fizz_buzz = fizz_buzz.skip(90);

    assert_eq!(&fizz_buzz.next().unwrap()[..], "98");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Buzz");
    assert!(fizz_buzz.next().is_none());
}