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}