use std::convert::TryFrom;
use crate::algorithm::Value;
use crate::error::InvalidStateError;
use super::Epoch;
use super::TwoPhaseCommitMessage;
#[derive(Clone)]
pub enum ParticipantMessage<V>
where
V: Value,
{
VoteRequest(Epoch, V),
Commit(Epoch),
Abort(Epoch),
DecisionRequest(Epoch),
}
impl<V> From<ParticipantMessage<V>> for TwoPhaseCommitMessage<V>
where
V: Value,
{
fn from(message: ParticipantMessage<V>) -> Self {
match message {
ParticipantMessage::VoteRequest(epoch, value) => {
TwoPhaseCommitMessage::VoteRequest(epoch, value)
}
ParticipantMessage::Commit(epoch) => TwoPhaseCommitMessage::Commit(epoch),
ParticipantMessage::Abort(epoch) => TwoPhaseCommitMessage::Abort(epoch),
ParticipantMessage::DecisionRequest(epoch) => {
TwoPhaseCommitMessage::DecisionRequest(epoch)
}
}
}
}
impl<V> TryFrom<TwoPhaseCommitMessage<V>> for ParticipantMessage<V>
where
V: Value,
{
type Error = InvalidStateError;
fn try_from(message: TwoPhaseCommitMessage<V>) -> Result<Self, Self::Error> {
match message {
TwoPhaseCommitMessage::VoteRequest(epoch, value) => {
Ok(ParticipantMessage::VoteRequest(epoch, value))
}
TwoPhaseCommitMessage::Commit(epoch) => Ok(ParticipantMessage::Commit(epoch)),
TwoPhaseCommitMessage::Abort(epoch) => Ok(ParticipantMessage::Abort(epoch)),
TwoPhaseCommitMessage::DecisionRequest(epoch) => {
Ok(ParticipantMessage::DecisionRequest(epoch))
}
TwoPhaseCommitMessage::VoteResponse(_, _) => Err(InvalidStateError::with_message(
"VoteResponse message cannot be handled by a participant".into(),
)),
TwoPhaseCommitMessage::DecisionAck(_) => Err(InvalidStateError::with_message(
"DecisionAck message cannot be handled by a participant".into(),
)),
}
}
}