use crate::protos::de_mls::messages::v1::{
ConversationUpdateRequest, conversation_update_request::Payload,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum ProposalKind {
Commit = 0,
StewardElection = 1,
Emergency = 2,
}
impl ProposalKind {
pub fn of(req: &ConversationUpdateRequest) -> Self {
match &req.payload {
Some(Payload::EmergencyCriteria(_)) => Self::Emergency,
Some(Payload::StewardElection(_)) => Self::StewardElection,
_ => Self::Commit,
}
}
pub fn is_emergency(self) -> bool {
self == Self::Emergency
}
pub fn is_steward_election(self) -> bool {
self == Self::StewardElection
}
pub fn is_mls_producing(self) -> bool {
self == Self::Commit
}
pub fn is_governance(self) -> bool {
!self.is_mls_producing()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::protos::de_mls::messages::v1::{
EmergencyCriteriaProposal, InviteMember, RemoveMember, StewardElectionProposal,
ViolationEvidence,
};
fn req(payload: Payload) -> ConversationUpdateRequest {
ConversationUpdateRequest {
payload: Some(payload),
}
}
#[test]
fn invite_and_remove_are_commit() {
assert_eq!(
ProposalKind::of(&req(Payload::InviteMember(InviteMember::default()))),
ProposalKind::Commit,
);
assert_eq!(
ProposalKind::of(&req(Payload::RemoveMember(RemoveMember::default()))),
ProposalKind::Commit,
);
}
#[test]
fn emergency_classified() {
let r = req(Payload::EmergencyCriteria(EmergencyCriteriaProposal {
evidence: Some(ViolationEvidence::broken_commit(vec![], 0, vec![])),
}));
let k = ProposalKind::of(&r);
assert_eq!(k, ProposalKind::Emergency);
assert!(k.is_emergency());
assert!(k.is_governance());
assert!(!k.is_mls_producing());
}
#[test]
fn steward_election_classified() {
let r = req(Payload::StewardElection(StewardElectionProposal {
proposed_stewards: vec![vec![1], vec![2]],
election_epoch: 5,
retry_round: 0,
}));
let k = ProposalKind::of(&r);
assert_eq!(k, ProposalKind::StewardElection);
assert!(k.is_steward_election());
assert!(k.is_governance());
}
#[test]
fn priority_ordering() {
assert!(ProposalKind::Emergency > ProposalKind::StewardElection);
assert!(ProposalKind::StewardElection > ProposalKind::Commit);
assert!(ProposalKind::Emergency > ProposalKind::Commit);
}
}