nodedb_array/sync/
replica_id.rs1use std::fmt;
11use std::str::FromStr;
12
13use serde::{Deserialize, Serialize};
14use uuid::Uuid;
15
16use crate::error::{ArrayError, ArrayResult};
17
18#[derive(
23 Copy,
24 Clone,
25 Debug,
26 PartialEq,
27 Eq,
28 Hash,
29 PartialOrd,
30 Ord,
31 Serialize,
32 Deserialize,
33 zerompk::ToMessagePack,
34 zerompk::FromMessagePack,
35)]
36pub struct ReplicaId(pub u64);
37
38impl ReplicaId {
39 pub const fn new(id: u64) -> Self {
42 Self(id)
43 }
44
45 pub fn generate() -> Self {
52 Self(Uuid::now_v7().as_u128() as u64)
53 }
54
55 pub fn as_u64(&self) -> u64 {
57 self.0
58 }
59}
60
61impl fmt::Display for ReplicaId {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 write!(f, "{:016x}", self.0)
65 }
66}
67
68impl FromStr for ReplicaId {
69 type Err = ArrayError;
70
71 fn from_str(s: &str) -> ArrayResult<Self> {
73 u64::from_str_radix(s, 16)
74 .map(ReplicaId)
75 .map_err(|_| ArrayError::InvalidReplicaId {
76 detail: format!("invalid replica_id hex: {s}"),
77 })
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn generate_is_unique() {
87 let a = ReplicaId::generate();
88 let b = ReplicaId::generate();
89 assert_ne!(a, b);
91 }
92
93 #[test]
94 fn roundtrip_hex() {
95 let id = ReplicaId::new(0xdeadbeef_cafebabe);
96 let s = id.to_string();
97 assert_eq!(s, "deadbeefcafebabe");
98 let parsed: ReplicaId = s.parse().unwrap();
99 assert_eq!(parsed, id);
100 }
101
102 #[test]
103 fn parse_invalid_returns_err() {
104 let result: ArrayResult<ReplicaId> = "not_hex_at_all!".parse();
105 assert!(matches!(result, Err(ArrayError::InvalidReplicaId { .. })));
106 }
107
108 #[test]
109 fn as_u64_round_trips() {
110 let val = 0x0102030405060708_u64;
111 let id = ReplicaId::new(val);
112 assert_eq!(id.as_u64(), val);
113 }
114
115 #[test]
116 fn serialize_roundtrip() {
117 let id = ReplicaId::generate();
118 let bytes = zerompk::to_msgpack_vec(&id).expect("serialize");
119 let back: ReplicaId = zerompk::from_msgpack(&bytes).expect("deserialize");
120 assert_eq!(id, back);
121 }
122}