#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Role {
Primary,
Replica,
Candidate,
}
impl Role {
pub fn as_str(self) -> &'static str {
match self {
Self::Primary => "primary",
Self::Replica => "replica",
Self::Candidate => "candidate",
}
}
pub fn parse(s: &[u8]) -> Option<Self> {
if s.eq_ignore_ascii_case(b"primary") {
Some(Self::Primary)
} else if s.eq_ignore_ascii_case(b"replica") {
Some(Self::Replica)
} else if s.eq_ignore_ascii_case(b"candidate") {
Some(Self::Candidate)
} else {
None
}
}
}
#[derive(Debug, Clone)]
pub enum Message {
Hb {
epoch: u64,
node_id: String,
role: Role,
repl_offset: u64,
},
Offer {
new_epoch: u64,
candidate_id: String,
repl_offset: u64,
},
Accept {
epoch: u64,
accepter_id: String,
},
Announce {
epoch: u64,
new_primary_id: String,
new_primary_addr: String,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn role_round_trip() {
for r in [Role::Primary, Role::Replica, Role::Candidate] {
assert_eq!(Role::parse(r.as_str().as_bytes()), Some(r));
}
}
#[test]
fn role_parse_case_insensitive() {
assert_eq!(Role::parse(b"PRIMARY"), Some(Role::Primary));
assert_eq!(Role::parse(b"Replica"), Some(Role::Replica));
assert_eq!(Role::parse(b"caNDidaTE"), Some(Role::Candidate));
}
#[test]
fn role_parse_unknown_is_none() {
assert_eq!(Role::parse(b"leader"), None);
assert_eq!(Role::parse(b""), None);
}
}