1use std::fmt;
7
8#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
10pub struct NodeId(pub u64);
11
12impl NodeId {
13 pub const ZERO: NodeId = NodeId(0);
14
15 #[inline]
16 pub fn new(id: u64) -> Self {
17 NodeId(id)
18 }
19
20 #[inline]
21 pub fn to_bytes(self) -> [u8; 8] {
22 self.0.to_le_bytes()
23 }
24
25 #[inline]
26 pub fn from_bytes(bytes: [u8; 8]) -> Self {
27 NodeId(u64::from_le_bytes(bytes))
28 }
29}
30
31impl fmt::Debug for NodeId {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 write!(f, "Node({:016x})", self.0)
34 }
35}
36
37impl fmt::Display for NodeId {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "{:016x}", self.0)
40 }
41}
42
43#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
45pub struct SessionId(pub u64);
46
47impl SessionId {
48 pub const ZERO: SessionId = SessionId(0);
49
50 #[inline]
51 pub fn new(id: u64) -> Self {
52 SessionId(id)
53 }
54
55 #[inline]
56 pub fn to_bytes(self) -> [u8; 8] {
57 self.0.to_le_bytes()
58 }
59
60 #[inline]
61 pub fn from_bytes(bytes: [u8; 8]) -> Self {
62 SessionId(u64::from_le_bytes(bytes))
63 }
64}
65
66impl fmt::Debug for SessionId {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 write!(f, "Session({:016x})", self.0)
69 }
70}
71
72#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
74pub struct StateId(pub u64);
75
76impl StateId {
77 pub const ZERO: StateId = StateId(0);
78
79 #[inline]
80 pub fn new(id: u64) -> Self {
81 StateId(id)
82 }
83
84 #[inline]
87 pub fn from_type_instance(state_type: u16, instance: u64) -> Self {
88 let id = ((state_type as u64) << 48) | (instance & 0x0000_FFFF_FFFF_FFFF);
89 StateId(id)
90 }
91
92 #[inline]
93 pub fn state_type(self) -> u16 {
94 (self.0 >> 48) as u16
95 }
96
97 #[inline]
98 pub fn instance(self) -> u64 {
99 self.0 & 0x0000_FFFF_FFFF_FFFF
100 }
101
102 #[inline]
103 pub fn to_bytes(self) -> [u8; 8] {
104 self.0.to_le_bytes()
105 }
106
107 #[inline]
108 pub fn from_bytes(bytes: [u8; 8]) -> Self {
109 StateId(u64::from_le_bytes(bytes))
110 }
111}
112
113impl fmt::Debug for StateId {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 write!(
116 f,
117 "State({:04x}:{:012x})",
118 self.state_type(),
119 self.instance()
120 )
121 }
122}
123
124impl fmt::Display for StateId {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 write!(f, "{:04x}:{:012x}", self.state_type(), self.instance())
127 }
128}
129
130#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
132pub struct EventId {
133 pub node: NodeId,
134 pub seq: u64,
135}
136
137impl EventId {
138 #[inline]
139 pub fn new(node: NodeId, seq: u64) -> Self {
140 EventId { node, seq }
141 }
142}
143
144impl fmt::Debug for EventId {
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 write!(f, "Event({:016x}:{})", self.node.0, self.seq)
147 }
148}
149
150#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
152pub struct MessageId(pub u64);
153
154impl MessageId {
155 #[inline]
156 pub fn new(id: u64) -> Self {
157 MessageId(id)
158 }
159
160 #[inline]
161 pub fn from_event(event_id: &EventId) -> Self {
162 let id = (event_id.node.0 ^ event_id.seq).wrapping_mul(0x517cc1b727220a95);
164 MessageId(id)
165 }
166}
167
168impl fmt::Debug for MessageId {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 write!(f, "Msg({:016x})", self.0)
171 }
172}
173
174#[cfg(test)]
175mod tests {
176 use super::*;
177
178 #[test]
179 fn test_node_id_roundtrip() {
180 let id = NodeId::new(0xDEADBEEF_CAFEBABE);
181 let bytes = id.to_bytes();
182 let recovered = NodeId::from_bytes(bytes);
183 assert_eq!(id, recovered);
184 }
185
186 #[test]
187 fn test_state_id_type_instance() {
188 let state_type = 0x0001; let instance = 0x0000_1234_5678_9ABC;
190 let id = StateId::from_type_instance(state_type, instance);
191
192 assert_eq!(id.state_type(), state_type);
193 assert_eq!(id.instance(), instance);
194 }
195
196 #[test]
197 fn test_state_id_instance_truncation() {
198 let state_type = 0x0002;
200 let instance = 0xFFFF_FFFF_FFFF_FFFF; let id = StateId::from_type_instance(state_type, instance);
202
203 assert_eq!(id.state_type(), state_type);
204 assert_eq!(id.instance(), 0x0000_FFFF_FFFF_FFFF); }
206}