use std::fmt::Debug;
use crate::LogEntry;
use crate::NodeInfo;
pub type ContextOf<S> = <S as State>::Context;
pub type ErrorOf<S> = <S as State>::Error;
pub type FrozenOf<S> = <S as State>::Frozen;
pub type LogEntryOf<S> = <S as State>::LogEntry;
pub type LogEntryIdOf<S> = <LogEntryOf<S> as LogEntry>::Id;
pub type NodeOf<S> = <S as State>::Node;
pub type NodeIdOf<S> = <NodeOf<S> as NodeInfo>::Id;
pub type OutcomeOf<S> = <S as State>::Outcome;
pub type EffectOf<S> = <S as State>::Effect;
pub trait State: 'static + Debug + Sized {
type Frozen: Frozen<Self> + Send + Sync + Debug;
type LogEntry: LogEntry;
type Context;
type Outcome: 'static + Clone + Debug + Send + Unpin;
type Effect: 'static + Send + Debug;
type Error: Send + Sync + 'static;
type Node: NodeInfo;
fn apply(
&mut self,
log_entry: &Self::LogEntry,
context: &mut Self::Context,
) -> Result<(Self::Outcome, Self::Effect), Self::Error>;
fn apply_unobserved(
&mut self,
log_entry: &Self::LogEntry,
context: &mut Self::Context,
) -> Result<Self::Effect, Self::Error> {
self.apply(log_entry, context)
.map(|(_outcome, effect)| effect)
}
#[allow(unused_variables)]
fn concurrency(this: Option<&Self>) -> Option<std::num::NonZeroUsize> {
Some(std::num::NonZeroUsize::new(1).unwrap())
}
fn cluster_at(&self, round_offset: std::num::NonZeroUsize) -> Vec<Self::Node>;
fn freeze(&self, context: &mut Self::Context) -> Self::Frozen;
}
pub trait Frozen<S: State> {
fn thaw(&self, context: &mut S::Context) -> S;
}
impl<S: State + Clone> Frozen<S> for S {
fn thaw(&self, _context: &mut S::Context) -> S {
self.clone()
}
}
pub fn concurrency_of<S: State>(state: &S) -> std::num::NonZeroUsize {
S::concurrency(Some(state)).expect("State::concurrency(Some(...)) returned None")
}