de_mls/core/
proposal_kind.rs1use crate::protos::de_mls::messages::v1::{
9 ConversationUpdateRequest, conversation_update_request::Payload,
10};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15pub enum ProposalKind {
16 Commit = 0,
18 StewardElection = 1,
20 Emergency = 2,
22}
23
24impl ProposalKind {
25 pub fn of(req: &ConversationUpdateRequest) -> Self {
27 match &req.payload {
28 Some(Payload::EmergencyCriteria(_)) => Self::Emergency,
29 Some(Payload::StewardElection(_)) => Self::StewardElection,
30 _ => Self::Commit,
31 }
32 }
33
34 pub fn is_emergency(self) -> bool {
35 self == Self::Emergency
36 }
37
38 pub fn is_steward_election(self) -> bool {
39 self == Self::StewardElection
40 }
41
42 pub fn is_mls_producing(self) -> bool {
45 self == Self::Commit
46 }
47
48 pub fn is_governance(self) -> bool {
50 !self.is_mls_producing()
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use crate::protos::de_mls::messages::v1::{
58 EmergencyCriteriaProposal, InviteMember, RemoveMember, StewardElectionProposal,
59 ViolationEvidence,
60 };
61
62 fn req(payload: Payload) -> ConversationUpdateRequest {
63 ConversationUpdateRequest {
64 payload: Some(payload),
65 }
66 }
67
68 #[test]
69 fn invite_and_remove_are_commit() {
70 assert_eq!(
71 ProposalKind::of(&req(Payload::InviteMember(InviteMember::default()))),
72 ProposalKind::Commit,
73 );
74 assert_eq!(
75 ProposalKind::of(&req(Payload::RemoveMember(RemoveMember::default()))),
76 ProposalKind::Commit,
77 );
78 }
79
80 #[test]
81 fn emergency_classified() {
82 let r = req(Payload::EmergencyCriteria(EmergencyCriteriaProposal {
83 evidence: Some(ViolationEvidence::broken_commit(vec![], 0, vec![])),
84 }));
85 let k = ProposalKind::of(&r);
86 assert_eq!(k, ProposalKind::Emergency);
87 assert!(k.is_emergency());
88 assert!(k.is_governance());
89 assert!(!k.is_mls_producing());
90 }
91
92 #[test]
93 fn steward_election_classified() {
94 let r = req(Payload::StewardElection(StewardElectionProposal {
95 proposed_stewards: vec![vec![1], vec![2]],
96 election_epoch: 5,
97 retry_round: 0,
98 }));
99 let k = ProposalKind::of(&r);
100 assert_eq!(k, ProposalKind::StewardElection);
101 assert!(k.is_steward_election());
102 assert!(k.is_governance());
103 }
104
105 #[test]
109 fn priority_ordering() {
110 assert!(ProposalKind::Emergency > ProposalKind::StewardElection);
111 assert!(ProposalKind::StewardElection > ProposalKind::Commit);
112 assert!(ProposalKind::Emergency > ProposalKind::Commit);
113 }
114}