Skip to main content

sim_lib_control/
generator.rs

1use sim_kernel::Ref;
2
3/// Outcome of advancing a [`Generator`]: a yielded value, or exhaustion.
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub enum GeneratorStep {
6    /// The next value the generator produces.
7    Yielded(Ref),
8    /// The generator has yielded every value and is drained.
9    Exhausted,
10}
11
12/// A single-lane generator that yields a fixed sequence of values on demand.
13///
14/// Models the yield-to-driver surface of generator control: each
15/// [`Generator::next_step`] resumes the generator and hands back the next value.
16///
17/// # Examples
18///
19/// ```
20/// use sim_kernel::{Ref, Symbol};
21/// use sim_lib_control::{Generator, GeneratorStep};
22///
23/// let one = Ref::Symbol(Symbol::new("one"));
24/// let mut generator = Generator::new(vec![one.clone()]);
25/// assert_eq!(generator.next_step(), GeneratorStep::Yielded(one));
26/// assert_eq!(generator.next_step(), GeneratorStep::Exhausted);
27/// assert!(generator.is_exhausted());
28/// ```
29#[derive(Clone, Debug, PartialEq, Eq)]
30pub struct Generator {
31    values: Vec<Ref>,
32    index: usize,
33}
34
35impl Generator {
36    /// Builds a generator that yields `values` in order.
37    pub fn new(values: Vec<Ref>) -> Self {
38        Self { values, index: 0 }
39    }
40
41    /// Advances the generator, returning the next [`GeneratorStep::Yielded`]
42    /// value or [`GeneratorStep::Exhausted`] once drained.
43    pub fn next_step(&mut self) -> GeneratorStep {
44        let Some(value) = self.values.get(self.index).cloned() else {
45            return GeneratorStep::Exhausted;
46        };
47        self.index += 1;
48        GeneratorStep::Yielded(value)
49    }
50
51    /// Returns whether every value has been yielded.
52    pub fn is_exhausted(&self) -> bool {
53        self.index >= self.values.len()
54    }
55}