use std::cmp::Ordering;
use std::net::SocketAddr;
use crate::stamps::{OpNumber, View, ViewTable};
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Request {
pub op: Vec<u8>,
pub c: u128,
pub s: u128,
pub v: View,
}
impl PartialOrd for Request {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.s.partial_cmp(&other.s).filter(|_| self.c == other.c)
}
}
impl From<Request> for Message {
fn from(value: Request) -> Self {
Message::Request(value)
}
}
#[derive(Clone, Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Reply {
pub v: View,
pub s: u128,
pub x: Vec<u8>,
}
impl From<Reply> for Message {
fn from(value: Reply) -> Self {
Message::Reply(value)
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Prepare {
pub v: View,
pub n: OpNumber,
pub m: Request,
pub c: OpNumber,
}
impl PartialOrd for Prepare {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(self.v, self.n).partial_cmp(&(other.v, other.n))
}
}
impl Ord for Prepare {
fn cmp(&self, other: &Self) -> Ordering {
(self.v, self.n).cmp(&(other.v, other.n))
}
}
impl From<Prepare> for Message {
fn from(value: Prepare) -> Self {
Message::Prepare(value)
}
}
#[derive(Clone, Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct PrepareOk {
pub v: View,
pub n: OpNumber,
pub i: usize,
}
impl From<PrepareOk> for Message {
fn from(value: PrepareOk) -> Self {
Message::PrepareOk(value)
}
}
#[derive(Clone, Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Inform {
pub v: View,
}
impl From<Inform> for Message {
fn from(value: Inform) -> Self {
Message::Inform(value)
}
}
#[derive(Clone, Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
pub struct Ping {
pub v: View,
pub c: OpNumber,
}
impl From<Ping> for Message {
fn from(value: Ping) -> Self {
Message::Ping(value)
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct DoViewChange {
pub v: View,
pub t: ViewTable,
pub l: Vec<Request>,
pub k: OpNumber,
pub i: usize
}
impl PartialOrd for DoViewChange {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(self.v, self.k).partial_cmp(&(other.v, other.k))
}
}
impl Ord for DoViewChange {
fn cmp(&self, other: &Self) -> Ordering {
(self.v, self.k).cmp(&(other.v, other.k))
}
}
impl From<DoViewChange> for Message {
fn from(value: DoViewChange) -> Self {
Message::DoViewChange(value)
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct StartView {
pub v: View,
pub t: ViewTable,
pub l: Vec<Request>,
pub k: OpNumber,
}
impl From<StartView> for Message {
fn from(value: StartView) -> Self {
Message::StartView(value)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Envelope {
pub view: View,
pub from: SocketAddr,
pub to: SocketAddr,
pub message: Message
}
impl Envelope {
pub fn new(view: View, from: SocketAddr, to: SocketAddr, message: impl Into<Message>) -> Self {
Self {
view,
from,
to,
message: message.into()
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Message {
Request(Request),
Prepare(Prepare),
PrepareOk(PrepareOk),
Reply(Reply),
Inform(Inform),
Ping(Ping),
DoViewChange(DoViewChange),
StartView(StartView),
}
impl Message {
pub fn view(&self) -> View {
match self {
Message::Request(request) => request.v,
Message::Prepare(prepare) => prepare.v,
Message::PrepareOk(prepare_ok) => prepare_ok.v,
Message::Reply(reply) => reply.v,
Message::Inform(inform) => inform.v,
Message::Ping(ping) => ping.v,
Message::DoViewChange(do_view_change) => do_view_change.v,
Message::StartView(start_view) => start_view.v,
}
}
}