use std::fmt;
use bigerror::reportable;
use tokio::time::Instant;
use tracing::error;
use uuid::Uuid;
pub mod ingress;
pub mod manager;
pub mod node;
pub mod notification;
pub mod queue;
pub mod storage;
pub mod timeout;
#[cfg(test)]
mod test_support;
pub use manager::{
HashKind, RexBuilder, Signal, SignalExt, SignalQueue, SmContext, StateMachine, StateMachineExt,
StateMachineManager,
};
pub use notification::{
GetTopic, Notification, NotificationManager, NotificationProcessor, Operation, Request,
RequestInner, RexMessage, RexTopic, Subscriber, UnaryRequest,
};
pub trait State: fmt::Debug + Send + PartialEq + Copy {
fn get_kind(&self) -> &dyn Kind<State = Self>;
fn fail(&mut self)
where
Self: Sized,
{
*self = self.get_kind().failed_state();
}
fn complete(&mut self)
where
Self: Sized,
{
*self = self.get_kind().completed_state();
}
fn is_completed(&self) -> bool
where
Self: Sized,
for<'a> &'a Self: PartialEq<&'a Self>,
{
self == &self.get_kind().completed_state()
}
fn is_failed(&self) -> bool
where
Self: Sized,
for<'a> &'a Self: PartialEq<&'a Self>,
{
self == &self.get_kind().failed_state()
}
fn is_new(&self) -> bool
where
Self: Sized,
for<'a> &'a Self: PartialEq<&'a Self>,
{
self == &self.get_kind().new_state()
}
fn is_terminal(&self) -> bool
where
Self: Sized,
{
self.is_failed() || self.is_completed()
}
fn kind_eq(&self, kind: &dyn Kind<State = Self>) -> bool
where
Self: Sized,
{
self.get_kind().new_state() == kind.new_state()
}
}
pub trait Kind: fmt::Debug + Send {
type State: State;
fn new_state(&self) -> Self::State;
fn failed_state(&self) -> Self::State;
fn completed_state(&self) -> Self::State;
}
pub trait Rex: Kind + HashKind {
type Input: Send + Sync + 'static + fmt::Debug;
type Message: RexMessage;
fn state_input(&self, state: <Self as Kind>::State) -> Option<Self::Input>;
fn timeout_input(&self, instant: Instant) -> Option<Self::Input>;
}
#[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)]
pub struct StateId<K: Kind> {
pub kind: K,
pub uuid: Uuid,
}
impl<K> std::ops::Deref for StateId<K>
where
K: Kind,
{
type Target = K;
fn deref(&self) -> &Self::Target {
&self.kind
}
}
impl<K> fmt::Display for StateId<K>
where
K: Kind,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?}<{}>)", self.kind, self.uuid)
}
}
impl<K: Kind> StateId<K> {
pub fn new(kind: K, uuid: Uuid) -> Self {
Self { kind, uuid }
}
pub fn new_rand(kind: K) -> Self {
Self::new(kind, Uuid::new_v4())
}
#[cfg(any(feature = "test", test))]
pub fn new_with_u128(kind: K, v: u128) -> Self {
Self {
kind,
uuid: Uuid::from_u128(v),
}
}
}
#[cfg(any(feature = "test", test))]
pub trait TestDefault {
fn test_default() -> Self;
}
#[derive(Debug, thiserror::Error)]
#[error("StateMachineError")]
pub struct StateMachineError;
reportable!(StateMachineError);