rust/src/libcore/ops/generator.rs

132 lines
5.2 KiB
Rust
Raw Normal View History

2016-12-26 14:34:03 +01:00
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/// The result of a generator resumption.
2017-07-10 09:30:57 -07:00
///
/// This enum is returned from the `Generator::resume` method and indicates the
/// possible return values of a generator. Currently this corresponds to either
/// a suspension point (`Yielded`) or a termination point (`Complete`).
2017-07-20 01:15:58 +02:00
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[cfg_attr(not(stage0), lang = "generator_state")]
2017-07-10 09:30:57 -07:00
#[unstable(feature = "generator_trait", issue = "43122")]
2017-07-20 01:16:12 +02:00
pub enum GeneratorState<Y, R> {
2016-12-26 14:34:03 +01:00
/// The generator suspended with a value.
2017-07-10 09:30:57 -07:00
///
/// This state indicates that a generator has been suspended, and typically
/// corresponds to a `yield` statement. The value provided in this variant
/// corresponds to the expression passed to `yield` and allows generators to
/// provide a value each time they yield.
2016-12-26 14:34:03 +01:00
Yielded(Y),
/// The generator completed with a return value.
2017-07-10 09:30:57 -07:00
///
/// This state indicates that a generator has finished execution with the
/// provided value. Once a generator has returned `Complete` it is
/// considered a programmer error to call `resume` again.
2016-12-26 14:34:03 +01:00
Complete(R),
}
/// The trait implemented by builtin generator types.
2017-07-10 09:30:57 -07:00
///
/// Generators, also commonly referred to as coroutines, are currently an
/// experimental language feature in Rust. Added in [RFC 2033] generators are
/// currently intended to primarily provide a building block for async/await
/// syntax but will likely extend to also providing an ergonomic definition for
/// iterators and other primitives.
///
/// The syntax and semantics for generators is unstable and will require a
/// further RFC for stabilization. At this time, though, the syntax is
/// closure-like:
///
/// ```rust
/// #![feature(generators, generator_trait)]
///
/// use std::ops::{Generator, State};
///
/// fn main() {
/// let mut generator = || {
/// yield 1;
/// return "foo"
/// };
///
2017-07-11 12:57:05 -07:00
/// match generator.resume() {
2017-07-10 09:30:57 -07:00
/// State::Yielded(1) => {}
/// _ => panic!("unexpected return from resume"),
/// }
2017-07-11 12:57:05 -07:00
/// match generator.resume() {
2017-07-10 09:30:57 -07:00
/// State::Complete("foo") => {}
/// _ => panic!("unexpected return from resume"),
/// }
/// }
/// ```
///
/// More documentation of generators can be found in the unstable book.
///
/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
#[cfg_attr(not(stage0), lang = "generator")]
2017-07-10 09:30:57 -07:00
#[unstable(feature = "generator_trait", issue = "43122")]
2016-12-26 14:34:03 +01:00
#[fundamental]
2017-07-11 12:57:05 -07:00
pub trait Generator {
2016-12-26 14:34:03 +01:00
/// The type of value this generator yields.
2017-07-10 09:30:57 -07:00
///
/// This associated type corresponds to the `yield` expression and the
/// values which are allowed to be returned each time a generator yields.
/// For example an iterator-as-a-generator would likely have this type as
/// `T`, the type being iterated over.
2016-12-26 14:34:03 +01:00
type Yield;
/// The type of value this generator returns.
2017-07-10 09:30:57 -07:00
///
/// This corresponds to the type returned from a generator either with a
/// `return` statement or implicitly as the last expression of a generator
/// literal. For example futures would use this as `Result<T, E>` as it
/// represents a completed future.
2016-12-26 14:34:03 +01:00
type Return;
2017-07-10 09:30:57 -07:00
/// Resumes the execution of this generator.
///
/// This function will resume execution of the generator or start execution
/// if it hasn't already. This call will return back into the generator's
/// last suspension point, resuming execution from the latest `yield`. The
/// generator will continue executing until it either yields or returns, at
/// which point this function will return.
///
/// # Return value
///
/// The `State` enum returned from this function indicates what state the
/// generator is in upon returning. If the `Yielded` variant is returned
/// then the generator has reached a suspension point and a value has been
/// yielded out. Generators in this state are available for resumption at a
/// later point.
///
/// If `Complete` is returned then the generator has completely finished
/// with the value provided. It is invalid for the generator to be resumed
/// again.
///
/// # Panics
///
/// This function may panic if it is called after the `Complete` variant has
/// been returned previously. While generator literals in the language are
/// guaranteed to panic on resuming after `Complete`, this is not guaranteed
/// for all implementations of the `Generator` trait.
2017-07-20 01:16:12 +02:00
fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
2016-12-26 14:34:03 +01:00
}
2017-07-10 09:30:57 -07:00
#[unstable(feature = "generator_trait", issue = "43122")]
2017-07-11 12:57:05 -07:00
impl<'a, T> Generator for &'a mut T
where T: Generator + ?Sized
{
type Yield = T::Yield;
type Return = T::Return;
2017-07-20 01:16:12 +02:00
fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
2017-07-11 12:57:05 -07:00
(**self).resume()
}
}