use std::borrow::Cow;
#[cfg(doctest)]
#[doc = include_str!("../README.md")]
mod readme_doctests {}
mod introspection;
pub mod projection;
#[doc(hidden)]
pub mod __private {
pub use crate::{
MachinePresentation, MachinePresentationDescriptor, RebuildAttempt, RebuildReport,
StatePresentation, TransitionPresentation, TransitionPresentationInventory,
};
pub use futures;
pub use linkme;
#[derive(Debug)]
pub struct TransitionToken {
_private: u8,
}
impl Default for TransitionToken {
fn default() -> Self {
Self::new()
}
}
impl TransitionToken {
pub const fn new() -> Self {
Self { _private: 0 }
}
}
}
pub use introspection::{
MachineDescriptor, MachineGraph, MachineIntrospection, MachinePresentation,
MachinePresentationDescriptor, MachineStateIdentity, MachineTransitionRecorder,
RecordedTransition, StateDescriptor, StatePresentation, TransitionDescriptor,
TransitionInventory, TransitionPresentation, TransitionPresentationInventory,
};
pub trait StateMarker {
type Data;
}
pub trait UnitState: StateMarker<Data = ()> {}
pub trait DataState: StateMarker {}
pub trait CanTransitionTo<Next> {
type Output;
fn transition_to(self) -> Self::Output;
}
pub trait CanTransitionWith<Data> {
type NextState;
type Output;
fn transition_with_data(self, data: Data) -> Self::Output;
}
pub trait CanTransitionMap<Next: StateMarker> {
type CurrentData;
type Output;
fn transition_map<F>(self, f: F) -> Self::Output
where
F: FnOnce(Self::CurrentData) -> Next::Data;
}
#[derive(Debug)]
pub enum Error {
InvalidState,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Branch<A, B> {
First(A),
Second(B),
}
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Rejection {
pub reason_key: &'static str,
pub message: Option<Cow<'static, str>>,
}
impl Rejection {
pub const fn new(reason_key: &'static str) -> Self {
Self {
reason_key,
message: None,
}
}
pub fn with_message(self, message: impl Into<Cow<'static, str>>) -> Self {
Self {
message: Some(message.into()),
..self
}
}
}
impl From<&'static str> for Rejection {
fn from(reason_key: &'static str) -> Self {
Self::new(reason_key)
}
}
impl core::fmt::Display for Rejection {
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match &self.message {
Some(message) => write!(fmt, "{}: {}", self.reason_key, message),
None => write!(fmt, "{}", self.reason_key),
}
}
}
impl std::error::Error for Rejection {}
pub type Validation<T> = core::result::Result<T, Rejection>;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RebuildAttempt {
pub validator: &'static str,
pub target_state: &'static str,
pub matched: bool,
pub reason_key: Option<&'static str>,
pub message: Option<Cow<'static, str>>,
}
#[derive(Debug)]
pub struct RebuildReport<M> {
pub attempts: Vec<RebuildAttempt>,
pub result: Result<M>,
}
impl<M> RebuildReport<M> {
pub fn matched_attempt(&self) -> Option<&RebuildAttempt> {
self.attempts.iter().find(|attempt| attempt.matched)
}
pub fn into_result(self) -> Result<M> {
self.result
}
}
impl<T> From<Error> for core::result::Result<T, Error> {
fn from(val: Error) -> Self {
Err(val)
}
}
impl core::fmt::Display for Error {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::result::Result<(), core::fmt::Error> {
write!(fmt, "{self:?}")
}
}
impl std::error::Error for Error {}