use crate::request::{ClientIdentifier, RequestIdentifier};
use crate::mailbox::Address;
use crate::stamps::{OpNumber, View};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Message {
pub from: Address,
pub to: Address,
pub view: View,
pub payload: Payload,
}
impl Message {
pub fn payload<P: TryFrom<Payload, Error = Payload>>(self) -> Result<P, Payload> {
P::try_from(self.payload)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Payload {
Request(Request),
Prepare(Prepare),
PrepareOk(PrepareOk),
Reply(Reply),
DoViewChange(DoViewChange),
StartView(StartView),
Commit(Commit),
OutdatedView,
ConcurrentRequest(ConcurrentRequest),
Recovery,
RecoveryResponse(RecoveryResponse),
}
impl From<Request> for Payload {
fn from(value: Request) -> Self {
Self::Request(value)
}
}
impl TryFrom<Payload> for Request {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::Request(r) => Ok(r),
_ => Err(value),
}
}
}
impl From<Prepare> for Payload {
fn from(value: Prepare) -> Self {
Self::Prepare(value)
}
}
impl TryFrom<Payload> for Prepare {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::Prepare(p) => Ok(p),
_ => Err(value),
}
}
}
impl From<PrepareOk> for Payload {
fn from(value: PrepareOk) -> Self {
Self::PrepareOk(value)
}
}
impl TryFrom<Payload> for PrepareOk {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::PrepareOk(p) => Ok(p),
_ => Err(value),
}
}
}
impl From<Reply> for Payload {
fn from(value: Reply) -> Self {
Self::Reply(value)
}
}
impl TryFrom<Payload> for Reply {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::Reply(r) => Ok(r),
_ => Err(value),
}
}
}
impl From<DoViewChange> for Payload {
fn from(value: DoViewChange) -> Self {
Self::DoViewChange(value)
}
}
impl TryFrom<Payload> for DoViewChange {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::DoViewChange(s) => Ok(s),
_ => Err(value),
}
}
}
impl From<StartView> for Payload {
fn from(value: StartView) -> Self {
Self::StartView(value)
}
}
impl TryFrom<Payload> for StartView {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::StartView(s) => Ok(s),
_ => Err(value),
}
}
}
impl From<Commit> for Payload {
fn from(value: Commit) -> Self {
Self::Commit(value)
}
}
impl TryFrom<Payload> for Commit {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::Commit(s) => Ok(s),
_ => Err(value),
}
}
}
impl From<ConcurrentRequest> for Payload {
fn from(value: ConcurrentRequest) -> Self {
Self::ConcurrentRequest(value)
}
}
impl TryFrom<Payload> for ConcurrentRequest {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::ConcurrentRequest(c) => Ok(c),
_ => Err(value),
}
}
}
impl From<RecoveryResponse> for Payload {
fn from(value: RecoveryResponse) -> Self {
Self::RecoveryResponse(value)
}
}
impl TryFrom<Payload> for RecoveryResponse {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::RecoveryResponse(c) => Ok(c),
_ => Err(value),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Request {
pub op: Vec<u8>,
pub c: ClientIdentifier,
pub s: RequestIdentifier,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Prepare {
pub n: OpNumber,
pub m: LogEntry,
pub k: OpNumber,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct PrepareOk {
pub n: OpNumber,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Reply {
pub x: Vec<u8>,
pub s: RequestIdentifier,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DoViewChange {
pub l: Vec<LogEntry>,
pub k: OpNumber,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct StartView {
pub l: Vec<LogEntry>,
pub k: OpNumber,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Commit {
pub k: OpNumber,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ConcurrentRequest {
pub s: RequestIdentifier,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RecoveryResponse {
pub l: Vec<LogEntry>,
pub k: OpNumber,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LogEntry {
pub request: Request,
pub prediction: Vec<u8>,
}
impl From<Request> for LogEntry {
fn from(request: Request) -> Self {
Self {
request,
prediction: vec![],
}
}
}