use std::ops::Deref;
pub struct Service<S: State> {
state: S,
}
impl<S: State> Service<S> {
pub fn new(state: S) -> Self {
Self { state }
}
pub fn execute(&mut self, command: S::Command, events: &mut Vec<S::Event>) {
self.state.decide(command, events);
for event in events {
self.state.evolve(event);
}
}
pub fn replay<'event>(
state: &mut S,
events: impl IntoIterator<Item = &'event S::Event>,
) where
<S as State>::Event: 'event,
{
for event in events {
state.evolve(event);
}
}
}
impl<S: State> Deref for Service<S> {
type Target = S;
fn deref(&self) -> &Self::Target {
&self.state
}
}
impl<S: State> Default for Service<S>
where
S: Default,
{
fn default() -> Self {
Self::new(S::default())
}
}
pub trait State {
type Command;
type Event;
fn decide(&self, command: Self::Command, events: &mut Vec<Self::Event>);
fn evolve(&mut self, event: &Self::Event);
}