Skip to main content

InMemoryJournal

Struct InMemoryJournal 

Source
pub struct InMemoryJournal<M, E, C> { /* private fields */ }
Available on crate feature journal only.
Expand description

An in-memory journal of TransitionRecord values.

Implementations§

Source§

impl<M, E, C> InMemoryJournal<M, E, C>

Source

pub const fn new() -> Self

Creates an empty journal.

Examples found in repository?
examples/replay.rs (line 91)
75fn main() {
76    let instrument = LabInstrument;
77    let mut runner = Runner::new(&instrument);
78
79    let events = [
80        Event::PowerOn,
81        Event::SensorReady,
82        Event::BeginMeasurement,
83        Event::DataCollected,
84        Event::DataCollected,
85        Event::AnomalyDetected,
86        Event::OperatorReset,
87        Event::BeginMeasurement,
88    ];
89
90    // Record every transition in the journal
91    let mut journal: InMemoryJournal<Mode, Event, Command> = InMemoryJournal::new();
92
93    println!("--- Recording transitions ---\n");
94    for event in events {
95        let from = runner.mode().clone();
96        let commands = runner.feed(&event);
97        let to = runner.mode().clone();
98
99        println!("  {from:?} + {event:?} => {to:?}");
100        if !commands.is_empty() {
101            println!("    commands: {commands:?}");
102        }
103
104        journal.record_step(&from, &to, &event, &commands);
105    }
106
107    println!("\n--- Journal: {} records ---\n", journal.len());
108    for record in journal.records() {
109        println!(
110            "  step {}: {:?} => {:?} (via {:?})",
111            record.step, record.from, record.to, record.event,
112        );
113    }
114
115    // Replay: feed the same events through a fresh machine and verify
116    println!("\n--- Replaying ---\n");
117    match journal.replay(&instrument, instrument.initial_mode()) {
118        Ok(final_mode) => {
119            println!("  replay verified: final mode = {final_mode:?}");
120            assert_eq!(final_mode, runner.mode().clone());
121        }
122        Err(err) => {
123            println!("  {err}");
124        }
125    }
126}
Source

pub fn len(&self) -> usize

Returns the number of records in the journal.

Examples found in repository?
examples/replay.rs (line 107)
75fn main() {
76    let instrument = LabInstrument;
77    let mut runner = Runner::new(&instrument);
78
79    let events = [
80        Event::PowerOn,
81        Event::SensorReady,
82        Event::BeginMeasurement,
83        Event::DataCollected,
84        Event::DataCollected,
85        Event::AnomalyDetected,
86        Event::OperatorReset,
87        Event::BeginMeasurement,
88    ];
89
90    // Record every transition in the journal
91    let mut journal: InMemoryJournal<Mode, Event, Command> = InMemoryJournal::new();
92
93    println!("--- Recording transitions ---\n");
94    for event in events {
95        let from = runner.mode().clone();
96        let commands = runner.feed(&event);
97        let to = runner.mode().clone();
98
99        println!("  {from:?} + {event:?} => {to:?}");
100        if !commands.is_empty() {
101            println!("    commands: {commands:?}");
102        }
103
104        journal.record_step(&from, &to, &event, &commands);
105    }
106
107    println!("\n--- Journal: {} records ---\n", journal.len());
108    for record in journal.records() {
109        println!(
110            "  step {}: {:?} => {:?} (via {:?})",
111            record.step, record.from, record.to, record.event,
112        );
113    }
114
115    // Replay: feed the same events through a fresh machine and verify
116    println!("\n--- Replaying ---\n");
117    match journal.replay(&instrument, instrument.initial_mode()) {
118        Ok(final_mode) => {
119            println!("  replay verified: final mode = {final_mode:?}");
120            assert_eq!(final_mode, runner.mode().clone());
121        }
122        Err(err) => {
123            println!("  {err}");
124        }
125    }
126}
Source

pub fn is_empty(&self) -> bool

Returns true if the journal is empty.

Source

pub fn records(&self) -> &[TransitionRecord<M, E, C>]

Returns a slice of all records.

Examples found in repository?
examples/replay.rs (line 108)
75fn main() {
76    let instrument = LabInstrument;
77    let mut runner = Runner::new(&instrument);
78
79    let events = [
80        Event::PowerOn,
81        Event::SensorReady,
82        Event::BeginMeasurement,
83        Event::DataCollected,
84        Event::DataCollected,
85        Event::AnomalyDetected,
86        Event::OperatorReset,
87        Event::BeginMeasurement,
88    ];
89
90    // Record every transition in the journal
91    let mut journal: InMemoryJournal<Mode, Event, Command> = InMemoryJournal::new();
92
93    println!("--- Recording transitions ---\n");
94    for event in events {
95        let from = runner.mode().clone();
96        let commands = runner.feed(&event);
97        let to = runner.mode().clone();
98
99        println!("  {from:?} + {event:?} => {to:?}");
100        if !commands.is_empty() {
101            println!("    commands: {commands:?}");
102        }
103
104        journal.record_step(&from, &to, &event, &commands);
105    }
106
107    println!("\n--- Journal: {} records ---\n", journal.len());
108    for record in journal.records() {
109        println!(
110            "  step {}: {:?} => {:?} (via {:?})",
111            record.step, record.from, record.to, record.event,
112        );
113    }
114
115    // Replay: feed the same events through a fresh machine and verify
116    println!("\n--- Replaying ---\n");
117    match journal.replay(&instrument, instrument.initial_mode()) {
118        Ok(final_mode) => {
119            println!("  replay verified: final mode = {final_mode:?}");
120            assert_eq!(final_mode, runner.mode().clone());
121        }
122        Err(err) => {
123            println!("  {err}");
124        }
125    }
126}
Source

pub fn append(&mut self, record: TransitionRecord<M, E, C>)

Appends a record.

Source

pub fn last(&self) -> Option<&TransitionRecord<M, E, C>>

Returns the most recent record, if any.

Source

pub fn record_step(&mut self, from: &M, to: &M, event: &E, commands: &[C])
where M: Clone, E: Clone, C: Clone,

Records a step by cloning the provided values.

This is a convenience for runtimes that keep Mode and Event by reference and want to capture an owned record.

Examples found in repository?
examples/replay.rs (line 104)
75fn main() {
76    let instrument = LabInstrument;
77    let mut runner = Runner::new(&instrument);
78
79    let events = [
80        Event::PowerOn,
81        Event::SensorReady,
82        Event::BeginMeasurement,
83        Event::DataCollected,
84        Event::DataCollected,
85        Event::AnomalyDetected,
86        Event::OperatorReset,
87        Event::BeginMeasurement,
88    ];
89
90    // Record every transition in the journal
91    let mut journal: InMemoryJournal<Mode, Event, Command> = InMemoryJournal::new();
92
93    println!("--- Recording transitions ---\n");
94    for event in events {
95        let from = runner.mode().clone();
96        let commands = runner.feed(&event);
97        let to = runner.mode().clone();
98
99        println!("  {from:?} + {event:?} => {to:?}");
100        if !commands.is_empty() {
101            println!("    commands: {commands:?}");
102        }
103
104        journal.record_step(&from, &to, &event, &commands);
105    }
106
107    println!("\n--- Journal: {} records ---\n", journal.len());
108    for record in journal.records() {
109        println!(
110            "  step {}: {:?} => {:?} (via {:?})",
111            record.step, record.from, record.to, record.event,
112        );
113    }
114
115    // Replay: feed the same events through a fresh machine and verify
116    println!("\n--- Replaying ---\n");
117    match journal.replay(&instrument, instrument.initial_mode()) {
118        Ok(final_mode) => {
119            println!("  replay verified: final mode = {final_mode:?}");
120            assert_eq!(final_mode, runner.mode().clone());
121        }
122        Err(err) => {
123            println!("  {err}");
124        }
125    }
126}
Source

pub fn transitions_from<'a>( &'a self, mode: &'a M, ) -> impl Iterator<Item = &'a TransitionRecord<M, E, C>> + 'a
where M: PartialEq,

Returns an iterator over records whose from mode matches mode.

Source

pub fn transitions_to<'a>( &'a self, mode: &'a M, ) -> impl Iterator<Item = &'a TransitionRecord<M, E, C>> + 'a
where M: PartialEq,

Returns an iterator over records whose to mode matches mode.

Source

pub fn replay<Mac>( &self, machine: &Mac, initial_mode: M, ) -> Result<M, ReplayError>
where Mac: Machine<Mode = M, Event = E, Command = C>, M: Clone + PartialEq, C: PartialEq,

Replays all records through machine, starting from initial_mode.

On success, returns the final mode after applying all decisions.

§Errors

Returns a ReplayError if replay diverges from the recorded history.

Examples found in repository?
examples/replay.rs (line 117)
75fn main() {
76    let instrument = LabInstrument;
77    let mut runner = Runner::new(&instrument);
78
79    let events = [
80        Event::PowerOn,
81        Event::SensorReady,
82        Event::BeginMeasurement,
83        Event::DataCollected,
84        Event::DataCollected,
85        Event::AnomalyDetected,
86        Event::OperatorReset,
87        Event::BeginMeasurement,
88    ];
89
90    // Record every transition in the journal
91    let mut journal: InMemoryJournal<Mode, Event, Command> = InMemoryJournal::new();
92
93    println!("--- Recording transitions ---\n");
94    for event in events {
95        let from = runner.mode().clone();
96        let commands = runner.feed(&event);
97        let to = runner.mode().clone();
98
99        println!("  {from:?} + {event:?} => {to:?}");
100        if !commands.is_empty() {
101            println!("    commands: {commands:?}");
102        }
103
104        journal.record_step(&from, &to, &event, &commands);
105    }
106
107    println!("\n--- Journal: {} records ---\n", journal.len());
108    for record in journal.records() {
109        println!(
110            "  step {}: {:?} => {:?} (via {:?})",
111            record.step, record.from, record.to, record.event,
112        );
113    }
114
115    // Replay: feed the same events through a fresh machine and verify
116    println!("\n--- Replaying ---\n");
117    match journal.replay(&instrument, instrument.initial_mode()) {
118        Ok(final_mode) => {
119            println!("  replay verified: final mode = {final_mode:?}");
120            assert_eq!(final_mode, runner.mode().clone());
121        }
122        Err(err) => {
123            println!("  {err}");
124        }
125    }
126}
Source

pub fn replay_with_error<Err, Mac>( &self, machine: &Mac, initial_mode: M, ) -> Result<M, ReplayError>
where Mac: Machine<Err, Mode = M, Event = E, Command = C>, M: Clone + PartialEq, C: PartialEq,

Replays all records through machine when the machine uses a non-default error type.

This is identical to InMemoryJournal::replay, but works with machines that are implemented as Machine<Err> rather than Machine (where Err is the default core::convert::Infallible).

§Errors

Returns a ReplayError if replay diverges from the recorded history.

Trait Implementations§

Source§

impl<M: Debug, E: Debug, C: Debug> Debug for InMemoryJournal<M, E, C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<M: Default, E: Default, C: Default> Default for InMemoryJournal<M, E, C>

Source§

fn default() -> InMemoryJournal<M, E, C>

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<M, E, C> Freeze for InMemoryJournal<M, E, C>

§

impl<M, E, C> RefUnwindSafe for InMemoryJournal<M, E, C>

§

impl<M, E, C> Send for InMemoryJournal<M, E, C>
where M: Send, E: Send, C: Send,

§

impl<M, E, C> Sync for InMemoryJournal<M, E, C>
where M: Sync, E: Sync, C: Sync,

§

impl<M, E, C> Unpin for InMemoryJournal<M, E, C>
where M: Unpin, E: Unpin, C: Unpin,

§

impl<M, E, C> UnsafeUnpin for InMemoryJournal<M, E, C>

§

impl<M, E, C> UnwindSafe for InMemoryJournal<M, E, C>
where M: UnwindSafe, E: UnwindSafe, C: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.