graphos_common/types/
id.rs1use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
11#[repr(transparent)]
12pub struct NodeId(pub u64);
13
14impl NodeId {
15 pub const INVALID: Self = Self(u64::MAX);
17
18 #[inline]
20 #[must_use]
21 pub const fn new(id: u64) -> Self {
22 Self(id)
23 }
24
25 #[inline]
27 #[must_use]
28 pub const fn as_u64(self) -> u64 {
29 self.0
30 }
31
32 #[inline]
34 #[must_use]
35 pub const fn is_valid(self) -> bool {
36 self.0 != u64::MAX
37 }
38}
39
40impl fmt::Debug for NodeId {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 if self.is_valid() {
43 write!(f, "NodeId({})", self.0)
44 } else {
45 write!(f, "NodeId(INVALID)")
46 }
47 }
48}
49
50impl fmt::Display for NodeId {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 write!(f, "{}", self.0)
53 }
54}
55
56impl From<u64> for NodeId {
57 fn from(id: u64) -> Self {
58 Self(id)
59 }
60}
61
62impl From<NodeId> for u64 {
63 fn from(id: NodeId) -> Self {
64 id.0
65 }
66}
67
68#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
72#[repr(transparent)]
73pub struct EdgeId(pub u64);
74
75impl EdgeId {
76 pub const INVALID: Self = Self(u64::MAX);
78
79 #[inline]
81 #[must_use]
82 pub const fn new(id: u64) -> Self {
83 Self(id)
84 }
85
86 #[inline]
88 #[must_use]
89 pub const fn as_u64(self) -> u64 {
90 self.0
91 }
92
93 #[inline]
95 #[must_use]
96 pub const fn is_valid(self) -> bool {
97 self.0 != u64::MAX
98 }
99}
100
101impl fmt::Debug for EdgeId {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 if self.is_valid() {
104 write!(f, "EdgeId({})", self.0)
105 } else {
106 write!(f, "EdgeId(INVALID)")
107 }
108 }
109}
110
111impl fmt::Display for EdgeId {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(f, "{}", self.0)
114 }
115}
116
117impl From<u64> for EdgeId {
118 fn from(id: u64) -> Self {
119 Self(id)
120 }
121}
122
123impl From<EdgeId> for u64 {
124 fn from(id: EdgeId) -> Self {
125 id.0
126 }
127}
128
129#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
133#[repr(transparent)]
134pub struct TxId(pub u64);
135
136impl TxId {
137 pub const INVALID: Self = Self(0);
139
140 #[inline]
142 #[must_use]
143 pub const fn new(id: u64) -> Self {
144 Self(id)
145 }
146
147 #[inline]
149 #[must_use]
150 pub const fn as_u64(self) -> u64 {
151 self.0
152 }
153
154 #[inline]
156 #[must_use]
157 pub const fn next(self) -> Self {
158 Self(self.0 + 1)
159 }
160
161 #[inline]
163 #[must_use]
164 pub const fn is_valid(self) -> bool {
165 self.0 != 0
166 }
167}
168
169impl fmt::Debug for TxId {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 if self.is_valid() {
172 write!(f, "TxId({})", self.0)
173 } else {
174 write!(f, "TxId(INVALID)")
175 }
176 }
177}
178
179impl fmt::Display for TxId {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 write!(f, "{}", self.0)
182 }
183}
184
185impl From<u64> for TxId {
186 fn from(id: u64) -> Self {
187 Self(id)
188 }
189}
190
191impl From<TxId> for u64 {
192 fn from(id: TxId) -> Self {
193 id.0
194 }
195}
196
197#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
203#[repr(transparent)]
204pub struct EpochId(pub u64);
205
206impl EpochId {
207 pub const INITIAL: Self = Self(0);
209
210 #[inline]
212 #[must_use]
213 pub const fn new(id: u64) -> Self {
214 Self(id)
215 }
216
217 #[inline]
219 #[must_use]
220 pub const fn as_u64(self) -> u64 {
221 self.0
222 }
223
224 #[inline]
226 #[must_use]
227 pub const fn next(self) -> Self {
228 Self(self.0 + 1)
229 }
230
231 #[inline]
235 #[must_use]
236 pub const fn is_visible_at(self, viewing_epoch: Self) -> bool {
237 self.0 <= viewing_epoch.0
238 }
239}
240
241impl fmt::Debug for EpochId {
242 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243 write!(f, "EpochId({})", self.0)
244 }
245}
246
247impl fmt::Display for EpochId {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 write!(f, "{}", self.0)
250 }
251}
252
253impl From<u64> for EpochId {
254 fn from(id: u64) -> Self {
255 Self(id)
256 }
257}
258
259impl From<EpochId> for u64 {
260 fn from(id: EpochId) -> Self {
261 id.0
262 }
263}
264
265#[cfg(test)]
266mod tests {
267 use super::*;
268
269 #[test]
270 fn test_node_id_basic() {
271 let id = NodeId::new(42);
272 assert_eq!(id.as_u64(), 42);
273 assert!(id.is_valid());
274 assert!(!NodeId::INVALID.is_valid());
275 }
276
277 #[test]
278 fn test_node_id_ordering() {
279 let id1 = NodeId::new(1);
280 let id2 = NodeId::new(2);
281 assert!(id1 < id2);
282 }
283
284 #[test]
285 fn test_edge_id_basic() {
286 let id = EdgeId::new(100);
287 assert_eq!(id.as_u64(), 100);
288 assert!(id.is_valid());
289 assert!(!EdgeId::INVALID.is_valid());
290 }
291
292 #[test]
293 fn test_tx_id_basic() {
294 let id = TxId::new(1);
295 assert!(id.is_valid());
296 assert!(!TxId::INVALID.is_valid());
297 assert_eq!(id.next(), TxId::new(2));
298 }
299
300 #[test]
301 fn test_epoch_visibility() {
302 let e1 = EpochId::new(1);
303 let e2 = EpochId::new(2);
304 let e3 = EpochId::new(3);
305
306 assert!(e1.is_visible_at(e2));
308 assert!(e1.is_visible_at(e3));
309
310 assert!(!e2.is_visible_at(e1));
312 assert!(e2.is_visible_at(e2));
313 assert!(e2.is_visible_at(e3));
314
315 assert!(!e3.is_visible_at(e1));
317 assert!(!e3.is_visible_at(e2));
318 assert!(e3.is_visible_at(e3));
319 }
320
321 #[test]
322 fn test_epoch_next() {
323 let e = EpochId::INITIAL;
324 assert_eq!(e.next(), EpochId::new(1));
325 assert_eq!(e.next().next(), EpochId::new(2));
326 }
327
328 #[test]
329 fn test_conversions() {
330 let node_id: NodeId = 42u64.into();
332 let raw: u64 = node_id.into();
333 assert_eq!(raw, 42);
334
335 let edge_id: EdgeId = 100u64.into();
337 let raw: u64 = edge_id.into();
338 assert_eq!(raw, 100);
339
340 let tx_id: TxId = 1u64.into();
342 let raw: u64 = tx_id.into();
343 assert_eq!(raw, 1);
344
345 let epoch_id: EpochId = 5u64.into();
347 let raw: u64 = epoch_id.into();
348 assert_eq!(raw, 5);
349 }
350}