Skip to main content

statum_core/
lib.rs

1//! Core error and result types shared by Statum crates.
2
3pub mod projection;
4
5/// A generated state marker type.
6pub trait StateMarker {
7    /// The payload type stored in machines for this state.
8    type Data;
9}
10
11/// A generated state marker with no payload.
12pub trait UnitState: StateMarker<Data = ()> {}
13
14/// A generated state marker that carries payload data.
15pub trait DataState: StateMarker {}
16
17/// A machine that can transition directly to `Next`.
18pub trait CanTransitionTo<Next> {
19    /// The transition result type.
20    type Output;
21
22    /// Perform the transition.
23    fn transition_to(self) -> Self::Output;
24}
25
26/// A machine that can transition using `Data`.
27pub trait CanTransitionWith<Data> {
28    /// The next state selected by this transition.
29    type NextState;
30    /// The transition result type.
31    type Output;
32
33    /// Perform the transition with payload data.
34    fn transition_with_data(self, data: Data) -> Self::Output;
35}
36
37/// A machine that can transition by mapping its current state data into `Next`.
38pub trait CanTransitionMap<Next: StateMarker> {
39    /// The payload type stored in the current state.
40    type CurrentData;
41    /// The transition result type.
42    type Output;
43
44    /// Perform the transition by consuming the current state data and producing the next payload.
45    fn transition_map<F>(self, f: F) -> Self::Output
46    where
47        F: FnOnce(Self::CurrentData) -> Next::Data;
48}
49
50/// Errors returned by Statum runtime helpers.
51#[derive(Debug)]
52pub enum Error {
53    /// Returned when a runtime check determines the current state is invalid.
54    InvalidState,
55}
56
57/// Convenience result alias used by Statum APIs.
58///
59/// # Example
60///
61/// ```
62/// fn ensure_ready(ready: bool) -> statum_core::Result<()> {
63///     if ready {
64///         Ok(())
65///     } else {
66///         Err(statum_core::Error::InvalidState)
67///     }
68/// }
69///
70/// assert!(ensure_ready(true).is_ok());
71/// assert!(ensure_ready(false).is_err());
72/// ```
73pub type Result<T> = core::result::Result<T, Error>;
74
75impl<T> From<Error> for core::result::Result<T, Error> {
76    fn from(val: Error) -> Self {
77        Err(val)
78    }
79}
80
81impl core::fmt::Display for Error {
82    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::result::Result<(), core::fmt::Error> {
83        write!(fmt, "{self:?}")
84    }
85}
86
87impl std::error::Error for Error {}