#![allow(clippy::module_name_repetitions)]
use std::fmt;
use bigerror::ThinContext;
use tokio::time::Instant;
use uuid::Uuid;
pub mod builder;
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 builder::RexBuilder;
pub use manager::{
HashKind, Signal, SignalExt, SignalQueue, SmContext, StateMachine, StateMachineExt,
StateMachineManager,
};
pub use notification::{
GetTopic, Notification, NotificationManager, NotificationProcessor, NotificationQueue,
Operation, Request, RequestInner, RexMessage, RexTopic, Subscriber, UnaryRequest,
};
pub use timeout::Timeout;
pub trait State: fmt::Debug + Send + PartialEq + Copy {
type Input: Send + Sync + 'static + fmt::Debug;
}
pub trait Kind: fmt::Debug + Send + Sized {
type State: State<Input = Self::Input> + AsRef<Self>;
type Input: Send + Sync + 'static + fmt::Debug;
fn new_state(&self) -> Self::State;
fn failed_state(&self) -> Self::State;
fn completed_state(&self) -> Self::State;
fn is_terminal(state: Self::State) -> bool {
let kind = state.as_ref();
kind.completed_state() == state || kind.failed_state() == state
}
}
pub trait Rex: Kind + HashKind
where
Self::State: AsRef<Self>,
{
type Message: RexMessage;
fn state_input(&self, state: Self::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.is_nil())
.then(|| bs58::encode(self.uuid).into_string())
.unwrap_or_else(|| "NIL".to_string())
)
}
}
impl<K: Kind> StateId<K> {
pub const fn new(kind: K, uuid: Uuid) -> Self {
Self { kind, uuid }
}
pub fn new_rand(kind: K) -> Self {
Self::new(kind, Uuid::new_v4())
}
pub const fn nil(kind: K) -> Self {
Self::new(kind, Uuid::nil())
}
pub fn is_nil(&self) -> bool {
self.uuid == Uuid::nil()
}
#[cfg(test)]
pub const fn new_with_u128(kind: K, v: u128) -> Self {
Self {
kind,
uuid: Uuid::from_u128(v),
}
}
}
#[derive(ThinContext)]
pub struct RexError;