use derive_more::From;
use super::{
boxed_io,
Awaiting,
IntoPhase,
LocalModelConfig,
NewRound,
Phase,
SendingSum,
SendingSum2,
SendingUpdate,
SerializableState,
SharedState,
State,
Sum,
Sum2,
Update,
};
use crate::{settings::PetSettings, ModelStore, Notify, XaynetClient};
#[derive(Debug)]
pub enum TransitionOutcome {
Pending(StateMachine),
Complete(StateMachine),
}
#[derive(From, Debug)]
pub enum StateMachine {
NewRound(Phase<NewRound>),
Awaiting(Phase<Awaiting>),
Sum(Phase<Sum>),
Update(Phase<Update>),
Sum2(Phase<Sum2>),
SendingSum(Phase<SendingSum>),
SendingUpdate(Phase<SendingUpdate>),
SendingSum2(Phase<SendingSum2>),
}
impl StateMachine {
pub async fn transition(self) -> TransitionOutcome {
match self {
StateMachine::NewRound(phase) => phase.step().await,
StateMachine::Awaiting(phase) => phase.step().await,
StateMachine::Sum(phase) => phase.step().await,
StateMachine::Update(phase) => phase.step().await,
StateMachine::Sum2(phase) => phase.step().await,
StateMachine::SendingSum(phase) => phase.step().await,
StateMachine::SendingUpdate(phase) => phase.step().await,
StateMachine::SendingSum2(phase) => phase.step().await,
}
}
pub fn save(self) -> SerializableState {
match self {
StateMachine::NewRound(phase) => phase.state.into(),
StateMachine::Awaiting(phase) => phase.state.into(),
StateMachine::Sum(phase) => phase.state.into(),
StateMachine::Update(phase) => phase.state.into(),
StateMachine::Sum2(phase) => phase.state.into(),
StateMachine::SendingSum(phase) => phase.state.into(),
StateMachine::SendingUpdate(phase) => phase.state.into(),
StateMachine::SendingSum2(phase) => phase.state.into(),
}
}
pub fn local_model_config(&self) -> LocalModelConfig {
match self {
StateMachine::NewRound(ref phase) => phase.local_model_config(),
StateMachine::Awaiting(ref phase) => phase.local_model_config(),
StateMachine::Sum(ref phase) => phase.local_model_config(),
StateMachine::Update(ref phase) => phase.local_model_config(),
StateMachine::Sum2(ref phase) => phase.local_model_config(),
StateMachine::SendingSum(ref phase) => phase.local_model_config(),
StateMachine::SendingUpdate(ref phase) => phase.local_model_config(),
StateMachine::SendingSum2(ref phase) => phase.local_model_config(),
}
}
}
impl StateMachine {
pub fn new<X, M, N>(
settings: PetSettings,
xaynet_client: X,
model_store: M,
notifier: N,
) -> Self
where
X: XaynetClient + Send + 'static,
M: ModelStore + Send + 'static,
N: Notify + Send + 'static,
{
let io = boxed_io(xaynet_client, model_store, notifier);
let state = State::new(Box::new(SharedState::new(settings)), Box::new(Awaiting));
state.into_phase(io).into()
}
pub fn restore<X, M, N>(
state: SerializableState,
xaynet_client: X,
model_store: M,
notifier: N,
) -> Self
where
X: XaynetClient + Send + 'static,
M: ModelStore + Send + 'static,
N: Notify + Send + 'static,
{
let io = boxed_io(xaynet_client, model_store, notifier);
match state {
SerializableState::NewRound(state) => state.into_phase(io).into(),
SerializableState::Awaiting(state) => state.into_phase(io).into(),
SerializableState::Sum(state) => state.into_phase(io).into(),
SerializableState::Sum2(state) => state.into_phase(io).into(),
SerializableState::Update(state) => state.into_phase(io).into(),
SerializableState::SendingSum(state) => state.into_phase(io).into(),
SerializableState::SendingUpdate(state) => state.into_phase(io).into(),
SerializableState::SendingSum2(state) => state.into_phase(io).into(),
}
}
}