Skip to main content

noxu_rep/
node_type.rs

1//! Replication node types.
2//!
3
4/// The type of a node within a replication group.
5///
6/// Each node type determines what role the node can play in the group,
7/// whether it participates in elections, and whether it stores data.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub enum NodeType {
10    /// An electable node that can serve as either master or replica.
11    /// Electable nodes participate in elections and store a complete
12    /// copy of the data.
13    Electable,
14
15    /// A monitor node that observes group state changes but does not
16    /// participate in elections or store data. Monitors receive
17    /// notifications about master changes and group membership.
18    Monitor,
19
20    /// A secondary node that replicates data from the master but
21    /// cannot be elected master. Secondary nodes do not participate
22    /// in elections or contribute to quorum calculations.
23    Secondary,
24
25    /// An arbiter node used for tie-breaking in elections. Arbiters
26    /// participate in elections and acknowledge transactions but do
27    /// not store a full copy of the data.
28    Arbiter,
29}
30
31impl NodeType {
32    /// Returns `true` if this node type can participate in elections.
33    ///
34    /// Electable nodes and arbiters participate in elections.
35    pub fn is_electable(&self) -> bool {
36        matches!(self, NodeType::Electable | NodeType::Arbiter)
37    }
38
39    /// Returns `true` if this node type stores a full copy of the data.
40    ///
41    /// Electable and secondary nodes are data nodes.
42    pub fn is_data_node(&self) -> bool {
43        matches!(self, NodeType::Electable | NodeType::Secondary)
44    }
45
46    /// Returns `true` if this node type can become master.
47    ///
48    /// Only electable nodes can become master.
49    pub fn can_be_master(&self) -> bool {
50        matches!(self, NodeType::Electable)
51    }
52}
53
54impl std::fmt::Display for NodeType {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        match self {
57            NodeType::Electable => write!(f, "ELECTABLE"),
58            NodeType::Monitor => write!(f, "MONITOR"),
59            NodeType::Secondary => write!(f, "SECONDARY"),
60            NodeType::Arbiter => write!(f, "ARBITER"),
61        }
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_is_electable() {
71        assert!(NodeType::Electable.is_electable());
72        assert!(!NodeType::Monitor.is_electable());
73        assert!(!NodeType::Secondary.is_electable());
74        assert!(NodeType::Arbiter.is_electable());
75    }
76
77    #[test]
78    fn test_is_data_node() {
79        assert!(NodeType::Electable.is_data_node());
80        assert!(!NodeType::Monitor.is_data_node());
81        assert!(NodeType::Secondary.is_data_node());
82        assert!(!NodeType::Arbiter.is_data_node());
83    }
84
85    #[test]
86    fn test_can_be_master() {
87        assert!(NodeType::Electable.can_be_master());
88        assert!(!NodeType::Monitor.can_be_master());
89        assert!(!NodeType::Secondary.can_be_master());
90        assert!(!NodeType::Arbiter.can_be_master());
91    }
92
93    #[test]
94    fn test_display() {
95        assert_eq!(NodeType::Electable.to_string(), "ELECTABLE");
96        assert_eq!(NodeType::Monitor.to_string(), "MONITOR");
97        assert_eq!(NodeType::Secondary.to_string(), "SECONDARY");
98        assert_eq!(NodeType::Arbiter.to_string(), "ARBITER");
99    }
100
101    #[test]
102    fn test_clone_and_copy() {
103        let nt = NodeType::Electable;
104        let cloned = nt;
105        let copied = nt;
106        assert_eq!(nt, cloned);
107        assert_eq!(nt, copied);
108    }
109
110    #[test]
111    fn test_eq_and_hash() {
112        use std::collections::HashSet;
113        let mut set = HashSet::new();
114        set.insert(NodeType::Electable);
115        set.insert(NodeType::Monitor);
116        set.insert(NodeType::Secondary);
117        set.insert(NodeType::Arbiter);
118        assert_eq!(set.len(), 4);
119
120        // Duplicate insert should not increase size.
121        set.insert(NodeType::Electable);
122        assert_eq!(set.len(), 4);
123    }
124
125    #[test]
126    fn test_debug() {
127        let s = format!("{:?}", NodeType::Electable);
128        assert_eq!(s, "Electable");
129    }
130}