use std::{
fmt::{self, Debug, Formatter},
ops::{BitOr, BitOrAssign},
};
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct PeerState(u8);
impl PeerState {
pub const VOTE: Self = PeerState(0b0000_1001);
pub const SEND: Self = PeerState(0b0000_0010);
pub const RECV: Self = PeerState(0b0000_0100);
pub const DKG: Self = PeerState(0b0000_1000);
pub fn inactive() -> Self {
PeerState(0)
}
pub fn active() -> Self {
Self::VOTE | Self::SEND | Self::RECV
}
pub fn contains(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
pub fn can_vote(self) -> bool {
self.contains(Self::VOTE)
}
pub fn can_dkg(self) -> bool {
self.contains(Self::DKG)
}
pub fn can_send(self) -> bool {
self.contains(Self::SEND)
}
pub fn can_recv(self) -> bool {
self.contains(Self::RECV)
}
}
impl BitOr for PeerState {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
PeerState(self.0 | rhs.0)
}
}
impl BitOrAssign for PeerState {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0
}
}
impl Debug for PeerState {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let mut separator = false;
write!(f, "PeerState(")?;
if self.contains(Self::VOTE) {
separator = true;
write!(f, "VOTE")?;
} else if self.contains(Self::DKG) {
separator = true;
write!(f, "DKG")?;
}
if self.contains(Self::SEND) {
if separator {
write!(f, "|")?;
}
separator = true;
write!(f, "SEND")?;
}
if self.contains(Self::RECV) {
if separator {
write!(f, "|")?;
}
write!(f, "RECV")?;
}
write!(f, ")")
}
}