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}