pub struct StateOwned<T, S> { /* private fields */ }Expand description
A directly owned runtime implementation T whose compile-time state is S.
Without the tracing feature, the state marker has no runtime storage and
StateOwned<T, S> has the same size and alignment as T.
With tracing, the wrapper also stores a Vec<TraceEntry> containing the
transition history for this value.
StateOwned is the simplest storage representation. Generic implementation
methods usually use State<SOwned, T, S> instead, because
the same method can then work for owned, boxed, pinned, shared-guard, and
discriminated storage. StateOwned<T, S> remains useful when you want the
direct transparent wrapper explicitly.
The state marker S is compile-time authority, not runtime data. A
transition consumes one state token and returns another:
use magicstatemachines::{StateOwned, transition};
use test_def::states::{Connected, Disconnected};
let disconnected: StateOwned<Connection, Disconnected> =
StateOwned::new(Connection::new("localhost:8080"));
let connected: StateOwned<Connection, Connected> = transition!(disconnected);When tracing is enabled, the same transition appends a diagnostic record.
The trace is historical only; it is not consulted to decide which methods
are callable. The compiler-enforced state remains the S type parameter.
let connected = transition!(disconnected);
let entry = &connected.trace()[0];
assert!(entry.from().type_name().ends_with("::Disconnected"));
assert!(entry.to().type_name().ends_with("::Connected"));use magicstatemachines::{State, StateOwned, SOwned, transition};
use test_def::states::{Connected, Disconnected};
let disconnected: StateOwned<Connection, Disconnected> =
StateOwned::new(Connection::new("localhost:8080"));
// Generic APIs usually spell the same owned state like this:
let disconnected: State<SOwned, Connection, Disconnected> =
State::new(Connection::new("localhost:8080"));
// State-specific methods are implemented on `Connection` with arbitrary
// self types, so they can accept this generic owned state directly.
let connected: State<SOwned, Connection, Connected> =
connection_method_that_connects(disconnected);State tokens are linear and shared ownership is not valid state storage:
use std::rc::Rc;
use magicstatemachines::{Initial, StateMachineImpl, StateOwned};
struct Machine;
struct Ready;
struct Runtime;
struct Token;
impl Initial<Ready> for Machine {}
impl StateMachineImpl for Runtime {
type Standin = Machine;
type Impl = Self;
type TransitionToken = Token;
}
let _: StateOwned<Rc<Runtime>, Ready> = StateOwned::new(Rc::new(Runtime));Implementations§
Source§impl<T, S> StateOwned<T, S>
impl<T, S> StateOwned<T, S>
Trait Implementations§
Source§impl<T, S> Clone for StateOwned<T, S>where
T: Clone,
S: StateClone,
impl<T, S> Clone for StateOwned<T, S>where
T: Clone,
S: StateClone,
impl<T, S> Copy for StateOwned<T, S>
tracing only.