pub struct InMemoryJournal<M, E, C> { /* private fields */ }journal only.Expand description
An in-memory journal of TransitionRecord values.
Implementations§
Source§impl<M, E, C> InMemoryJournal<M, E, C>
impl<M, E, C> InMemoryJournal<M, E, C>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates an empty journal.
Examples found in repository?
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}Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of records in the journal.
Examples found in repository?
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}Sourcepub fn records(&self) -> &[TransitionRecord<M, E, C>]
pub fn records(&self) -> &[TransitionRecord<M, E, C>]
Returns a slice of all records.
Examples found in repository?
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}Sourcepub fn append(&mut self, record: TransitionRecord<M, E, C>)
pub fn append(&mut self, record: TransitionRecord<M, E, C>)
Appends a record.
Sourcepub fn last(&self) -> Option<&TransitionRecord<M, E, C>>
pub fn last(&self) -> Option<&TransitionRecord<M, E, C>>
Returns the most recent record, if any.
Sourcepub fn record_step(&mut self, from: &M, to: &M, event: &E, commands: &[C])
pub fn record_step(&mut self, from: &M, to: &M, event: &E, commands: &[C])
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?
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}Sourcepub fn transitions_from<'a>(
&'a self,
mode: &'a M,
) -> impl Iterator<Item = &'a TransitionRecord<M, E, C>> + 'awhere
M: PartialEq,
pub fn transitions_from<'a>(
&'a self,
mode: &'a M,
) -> impl Iterator<Item = &'a TransitionRecord<M, E, C>> + 'awhere
M: PartialEq,
Returns an iterator over records whose from mode matches mode.
Sourcepub fn transitions_to<'a>(
&'a self,
mode: &'a M,
) -> impl Iterator<Item = &'a TransitionRecord<M, E, C>> + 'awhere
M: PartialEq,
pub fn transitions_to<'a>(
&'a self,
mode: &'a M,
) -> impl Iterator<Item = &'a TransitionRecord<M, E, C>> + 'awhere
M: PartialEq,
Returns an iterator over records whose to mode matches mode.
Sourcepub fn replay<Mac>(
&self,
machine: &Mac,
initial_mode: M,
) -> Result<M, ReplayError>
pub fn replay<Mac>( &self, machine: &Mac, initial_mode: M, ) -> Result<M, ReplayError>
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?
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}Sourcepub fn replay_with_error<Err, Mac>(
&self,
machine: &Mac,
initial_mode: M,
) -> Result<M, ReplayError>
pub fn replay_with_error<Err, Mac>( &self, machine: &Mac, initial_mode: M, ) -> Result<M, ReplayError>
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.