pub struct StateHistory<S: State> { /* private fields */ }Expand description
Ordered history of state transitions.
History is immutable - the record method returns a new history
with the transition added, following functional programming principles.
§Example
use mindset::core::{State, StateHistory, StateTransition};
use serde::{Deserialize, Serialize};
use chrono::Utc;
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
enum WorkState {
Start,
Middle,
End,
}
impl State for WorkState {
fn name(&self) -> &str {
match self {
Self::Start => "Start",
Self::Middle => "Middle",
Self::End => "End",
}
}
}
let history = StateHistory::new();
let transition1 = StateTransition {
from: WorkState::Start,
to: WorkState::Middle,
timestamp: Utc::now(),
attempt: 1,
};
let history = history.record(transition1);
let transition2 = StateTransition {
from: WorkState::Middle,
to: WorkState::End,
timestamp: Utc::now(),
attempt: 1,
};
let history = history.record(transition2);
let path = history.get_path();
assert_eq!(path.len(), 3); // Start -> Middle -> EndImplementations§
Source§impl<S: State> StateHistory<S>
impl<S: State> StateHistory<S>
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new empty history.
§Example
use mindset::core::{State, StateHistory};
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
enum Status { Active }
impl State for Status {
fn name(&self) -> &str { "Active" }
}
let history: StateHistory<Status> = StateHistory::new();
assert_eq!(history.transitions().len(), 0);Sourcepub fn record(&self, transition: StateTransition<S>) -> Self
pub fn record(&self, transition: StateTransition<S>) -> Self
Record a transition, returning a new history.
This is a pure function - it does not mutate the existing history but returns a new one with the transition added.
§Example
use mindset::core::{State, StateHistory, StateTransition};
use serde::{Deserialize, Serialize};
use chrono::Utc;
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
enum Step { A, B }
impl State for Step {
fn name(&self) -> &str {
match self {
Self::A => "A",
Self::B => "B",
}
}
}
let history = StateHistory::new();
let transition = StateTransition {
from: Step::A,
to: Step::B,
timestamp: Utc::now(),
attempt: 1,
};
let new_history = history.record(transition);
assert_eq!(new_history.transitions().len(), 1);
assert_eq!(history.transitions().len(), 0); // Original unchangedSourcepub fn get_path(&self) -> Vec<&S>
pub fn get_path(&self) -> Vec<&S>
Get the path of states traversed.
Returns references to states in order: initial state, then
the to state of each transition.
§Example
use mindset::core::{State, StateHistory, StateTransition};
use serde::{Deserialize, Serialize};
use chrono::Utc;
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
enum Phase { One, Two, Three }
impl State for Phase {
fn name(&self) -> &str {
match self {
Self::One => "One",
Self::Two => "Two",
Self::Three => "Three",
}
}
}
let mut history = StateHistory::new();
history = history.record(StateTransition {
from: Phase::One,
to: Phase::Two,
timestamp: Utc::now(),
attempt: 1,
});
history = history.record(StateTransition {
from: Phase::Two,
to: Phase::Three,
timestamp: Utc::now(),
attempt: 1,
});
let path = history.get_path();
assert_eq!(path.len(), 3);
assert_eq!(path[0], &Phase::One);
assert_eq!(path[1], &Phase::Two);
assert_eq!(path[2], &Phase::Three);Sourcepub fn duration(&self) -> Option<Duration>
pub fn duration(&self) -> Option<Duration>
Calculate total duration from first to last transition.
Returns None if there are no transitions. Otherwise returns
the duration between the first and last transition timestamps.
§Example
use mindset::core::{State, StateHistory, StateTransition};
use serde::{Deserialize, Serialize};
use chrono::Utc;
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
enum State1 { A, B }
impl State for State1 {
fn name(&self) -> &str {
match self {
Self::A => "A",
Self::B => "B",
}
}
}
let history = StateHistory::new();
assert!(history.duration().is_none());
let start = Utc::now();
let history = history.record(StateTransition {
from: State1::A,
to: State1::B,
timestamp: start,
attempt: 1,
});
assert!(history.duration().is_some());Sourcepub fn transitions(&self) -> &[StateTransition<S>]
pub fn transitions(&self) -> &[StateTransition<S>]
Get all transitions.
Returns a slice of all recorded transitions in order.
§Example
use mindset::core::{State, StateHistory, StateTransition};
use serde::{Deserialize, Serialize};
use chrono::Utc;
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
enum MyState { X, Y }
impl State for MyState {
fn name(&self) -> &str {
match self {
Self::X => "X",
Self::Y => "Y",
}
}
}
let history = StateHistory::new();
let history = history.record(StateTransition {
from: MyState::X,
to: MyState::Y,
timestamp: Utc::now(),
attempt: 1,
});
assert_eq!(history.transitions().len(), 1);Trait Implementations§
Source§impl<S: Clone + State> Clone for StateHistory<S>
impl<S: Clone + State> Clone for StateHistory<S>
Source§fn clone(&self) -> StateHistory<S>
fn clone(&self) -> StateHistory<S>
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl<S: State> Default for StateHistory<S>
impl<S: State> Default for StateHistory<S>
Source§impl<'de, S: State> Deserialize<'de> for StateHistory<S>
impl<'de, S: State> Deserialize<'de> for StateHistory<S>
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
Auto Trait Implementations§
impl<S> Freeze for StateHistory<S>
impl<S> RefUnwindSafe for StateHistory<S>where
S: RefUnwindSafe,
impl<S> Send for StateHistory<S>
impl<S> Sync for StateHistory<S>
impl<S> Unpin for StateHistory<S>where
S: Unpin,
impl<S> UnwindSafe for StateHistory<S>where
S: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more