genawaiter/
ops.rs

1use std::pin::Pin;
2
3/// A trait implemented for coroutines.
4///
5/// A `Coroutine` is a generalization of a `Generator`. A `Generator` constrains
6/// the resume argument type to `()`, but in a `Coroutine` it can be anything.
7pub trait Coroutine {
8    /// The type of value this generator yields.
9    type Yield;
10
11    /// The type of value this generator accepts as a resume argument.
12    type Resume;
13
14    /// The type of value this generator returns upon completion.
15    type Return;
16
17    /// Resumes the execution of this generator.
18    ///
19    /// The argument will be passed into the coroutine as a resume argument.
20    fn resume_with(
21        self: Pin<&mut Self>,
22        arg: Self::Resume,
23    ) -> GeneratorState<Self::Yield, Self::Return>;
24}
25
26/// A trait implemented for generator types.
27///
28/// This is modeled after the stdlib's nightly-only [`std::ops::Generator`].
29pub trait Generator {
30    /// The type of value this generator yields.
31    type Yield;
32
33    /// The type of value this generator returns upon completion.
34    type Return;
35
36    /// Resumes the execution of this generator.
37    fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return>;
38}
39
40impl<C: Coroutine<Resume = ()>> Generator for C {
41    type Yield = <Self as Coroutine>::Yield;
42    type Return = <Self as Coroutine>::Return;
43
44    #[must_use]
45    fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return> {
46        self.resume_with(())
47    }
48}
49
50/// The result of a generator resumption.
51///
52/// This is modeled after the stdlib's nightly-only
53/// [`std::ops::GeneratorState`].
54#[derive(PartialEq, Debug)]
55#[allow(clippy::module_name_repetitions)]
56pub enum GeneratorState<Y, R> {
57    /// The generator suspended with a value.
58    Yielded(Y),
59
60    /// The generator completed with a return value.
61    Complete(R),
62}