1use serde::{Deserialize, Serialize};
7use std::fmt;
8
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
24#[repr(transparent)]
25pub struct NodeId(pub u64);
26
27impl NodeId {
28 pub const INVALID: Self = Self(u64::MAX);
30
31 #[inline]
33 #[must_use]
34 pub const fn new(id: u64) -> Self {
35 Self(id)
36 }
37
38 #[inline]
40 #[must_use]
41 pub const fn as_u64(&self) -> u64 {
42 self.0
43 }
44
45 #[inline]
47 #[must_use]
48 pub const fn is_valid(&self) -> bool {
49 self.0 != u64::MAX
50 }
51}
52
53impl fmt::Debug for NodeId {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 if self.is_valid() {
56 write!(f, "NodeId({})", self.0)
57 } else {
58 write!(f, "NodeId(INVALID)")
59 }
60 }
61}
62
63impl fmt::Display for NodeId {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 write!(f, "{}", self.0)
66 }
67}
68
69impl From<u64> for NodeId {
70 fn from(id: u64) -> Self {
71 Self(id)
72 }
73}
74
75impl From<NodeId> for u64 {
76 fn from(id: NodeId) -> Self {
77 id.0
78 }
79}
80
81#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
86#[repr(transparent)]
87pub struct EdgeId(pub u64);
88
89impl EdgeId {
90 pub const INVALID: Self = Self(u64::MAX);
92
93 #[inline]
95 #[must_use]
96 pub const fn new(id: u64) -> Self {
97 Self(id)
98 }
99
100 #[inline]
102 #[must_use]
103 pub const fn as_u64(&self) -> u64 {
104 self.0
105 }
106
107 #[inline]
109 #[must_use]
110 pub const fn is_valid(&self) -> bool {
111 self.0 != u64::MAX
112 }
113}
114
115impl fmt::Debug for EdgeId {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 if self.is_valid() {
118 write!(f, "EdgeId({})", self.0)
119 } else {
120 write!(f, "EdgeId(INVALID)")
121 }
122 }
123}
124
125impl fmt::Display for EdgeId {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 write!(f, "{}", self.0)
128 }
129}
130
131impl From<u64> for EdgeId {
132 fn from(id: u64) -> Self {
133 Self(id)
134 }
135}
136
137impl From<EdgeId> for u64 {
138 fn from(id: EdgeId) -> Self {
139 id.0
140 }
141}
142
143#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
148#[repr(transparent)]
149pub struct TransactionId(pub u64);
150
151impl TransactionId {
152 pub const INVALID: Self = Self(u64::MAX);
154
155 pub const SYSTEM: Self = Self(1);
158
159 #[inline]
161 #[must_use]
162 pub const fn new(id: u64) -> Self {
163 Self(id)
164 }
165
166 #[inline]
168 #[must_use]
169 pub const fn as_u64(&self) -> u64 {
170 self.0
171 }
172
173 #[inline]
175 #[must_use]
176 pub const fn next(&self) -> Self {
177 Self(self.0 + 1)
178 }
179
180 #[inline]
182 #[must_use]
183 pub const fn is_valid(&self) -> bool {
184 self.0 != u64::MAX
185 }
186}
187
188impl fmt::Debug for TransactionId {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 if self.is_valid() {
191 write!(f, "TransactionId({})", self.0)
192 } else {
193 write!(f, "TransactionId(INVALID)")
194 }
195 }
196}
197
198impl fmt::Display for TransactionId {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 write!(f, "{}", self.0)
201 }
202}
203
204impl From<u64> for TransactionId {
205 fn from(id: u64) -> Self {
206 Self(id)
207 }
208}
209
210impl From<TransactionId> for u64 {
211 fn from(id: TransactionId) -> Self {
212 id.0
213 }
214}
215
216#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
222#[repr(transparent)]
223pub struct EpochId(pub u64);
224
225impl EpochId {
226 pub const INITIAL: Self = Self(0);
228
229 pub const PENDING: Self = Self(u64::MAX);
236
237 #[inline]
239 #[must_use]
240 pub const fn new(id: u64) -> Self {
241 Self(id)
242 }
243
244 #[inline]
246 #[must_use]
247 pub const fn as_u64(&self) -> u64 {
248 self.0
249 }
250
251 #[inline]
253 #[must_use]
254 pub const fn next(&self) -> Self {
255 Self(self.0 + 1)
256 }
257
258 #[inline]
262 #[must_use]
263 pub const fn is_visible_at(&self, viewing_epoch: Self) -> bool {
264 self.0 <= viewing_epoch.0
265 }
266}
267
268impl fmt::Debug for EpochId {
269 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
270 write!(f, "EpochId({})", self.0)
271 }
272}
273
274impl fmt::Display for EpochId {
275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276 write!(f, "{}", self.0)
277 }
278}
279
280impl From<u64> for EpochId {
281 fn from(id: u64) -> Self {
282 Self(id)
283 }
284}
285
286impl From<EpochId> for u64 {
287 fn from(id: EpochId) -> Self {
288 id.0
289 }
290}
291
292#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
297#[repr(transparent)]
298pub struct LabelId(pub u32);
299
300impl LabelId {
301 pub const INVALID: Self = Self(u32::MAX);
303
304 #[inline]
306 #[must_use]
307 pub const fn new(id: u32) -> Self {
308 Self(id)
309 }
310
311 #[inline]
313 #[must_use]
314 pub const fn as_u32(&self) -> u32 {
315 self.0
316 }
317
318 #[inline]
320 #[must_use]
321 pub const fn is_valid(&self) -> bool {
322 self.0 != u32::MAX
323 }
324}
325
326impl fmt::Debug for LabelId {
327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328 if self.is_valid() {
329 write!(f, "LabelId({})", self.0)
330 } else {
331 write!(f, "LabelId(INVALID)")
332 }
333 }
334}
335
336impl fmt::Display for LabelId {
337 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
338 write!(f, "{}", self.0)
339 }
340}
341
342impl From<u32> for LabelId {
343 fn from(id: u32) -> Self {
344 Self(id)
345 }
346}
347
348impl From<LabelId> for u32 {
349 fn from(id: LabelId) -> Self {
350 id.0
351 }
352}
353
354#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
359#[repr(transparent)]
360pub struct PropertyKeyId(pub u32);
361
362impl PropertyKeyId {
363 pub const INVALID: Self = Self(u32::MAX);
365
366 #[inline]
368 #[must_use]
369 pub const fn new(id: u32) -> Self {
370 Self(id)
371 }
372
373 #[inline]
375 #[must_use]
376 pub const fn as_u32(&self) -> u32 {
377 self.0
378 }
379
380 #[inline]
382 #[must_use]
383 pub const fn is_valid(&self) -> bool {
384 self.0 != u32::MAX
385 }
386}
387
388impl fmt::Debug for PropertyKeyId {
389 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
390 if self.is_valid() {
391 write!(f, "PropertyKeyId({})", self.0)
392 } else {
393 write!(f, "PropertyKeyId(INVALID)")
394 }
395 }
396}
397
398impl fmt::Display for PropertyKeyId {
399 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400 write!(f, "{}", self.0)
401 }
402}
403
404impl From<u32> for PropertyKeyId {
405 fn from(id: u32) -> Self {
406 Self(id)
407 }
408}
409
410impl From<PropertyKeyId> for u32 {
411 fn from(id: PropertyKeyId) -> Self {
412 id.0
413 }
414}
415
416#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
421#[repr(transparent)]
422pub struct EdgeTypeId(pub u32);
423
424impl EdgeTypeId {
425 pub const INVALID: Self = Self(u32::MAX);
427
428 #[inline]
430 #[must_use]
431 pub const fn new(id: u32) -> Self {
432 Self(id)
433 }
434
435 #[inline]
437 #[must_use]
438 pub const fn as_u32(&self) -> u32 {
439 self.0
440 }
441
442 #[inline]
444 #[must_use]
445 pub const fn is_valid(&self) -> bool {
446 self.0 != u32::MAX
447 }
448}
449
450impl fmt::Debug for EdgeTypeId {
451 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
452 if self.is_valid() {
453 write!(f, "EdgeTypeId({})", self.0)
454 } else {
455 write!(f, "EdgeTypeId(INVALID)")
456 }
457 }
458}
459
460impl fmt::Display for EdgeTypeId {
461 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
462 write!(f, "{}", self.0)
463 }
464}
465
466impl From<u32> for EdgeTypeId {
467 fn from(id: u32) -> Self {
468 Self(id)
469 }
470}
471
472impl From<EdgeTypeId> for u32 {
473 fn from(id: EdgeTypeId) -> Self {
474 id.0
475 }
476}
477
478#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
480#[repr(transparent)]
481pub struct IndexId(pub u32);
482
483impl IndexId {
484 pub const INVALID: Self = Self(u32::MAX);
486
487 #[inline]
489 #[must_use]
490 pub const fn new(id: u32) -> Self {
491 Self(id)
492 }
493
494 #[inline]
496 #[must_use]
497 pub const fn as_u32(&self) -> u32 {
498 self.0
499 }
500
501 #[inline]
503 #[must_use]
504 pub const fn is_valid(&self) -> bool {
505 self.0 != u32::MAX
506 }
507}
508
509impl fmt::Debug for IndexId {
510 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
511 if self.is_valid() {
512 write!(f, "IndexId({})", self.0)
513 } else {
514 write!(f, "IndexId(INVALID)")
515 }
516 }
517}
518
519impl fmt::Display for IndexId {
520 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
521 write!(f, "{}", self.0)
522 }
523}
524
525impl From<u32> for IndexId {
526 fn from(id: u32) -> Self {
527 Self(id)
528 }
529}
530
531impl From<IndexId> for u32 {
532 fn from(id: IndexId) -> Self {
533 id.0
534 }
535}
536
537#[cfg(test)]
538mod tests {
539 use super::*;
540
541 #[test]
542 fn test_node_id_basic() {
543 let id = NodeId::new(42);
544 assert_eq!(id.as_u64(), 42);
545 assert!(id.is_valid());
546 assert!(!NodeId::INVALID.is_valid());
547 }
548
549 #[test]
550 fn test_node_id_ordering() {
551 let id1 = NodeId::new(1);
552 let id2 = NodeId::new(2);
553 assert!(id1 < id2);
554 }
555
556 #[test]
557 fn test_edge_id_basic() {
558 let id = EdgeId::new(100);
559 assert_eq!(id.as_u64(), 100);
560 assert!(id.is_valid());
561 assert!(!EdgeId::INVALID.is_valid());
562 }
563
564 #[test]
565 fn test_tx_id_basic() {
566 let id = TransactionId::new(1);
567 assert!(id.is_valid());
568 assert!(!TransactionId::INVALID.is_valid());
569 assert_eq!(id.next(), TransactionId::new(2));
570 }
571
572 #[test]
573 fn test_epoch_visibility() {
574 let e1 = EpochId::new(1);
575 let e2 = EpochId::new(2);
576 let e3 = EpochId::new(3);
577
578 assert!(e1.is_visible_at(e2));
580 assert!(e1.is_visible_at(e3));
581
582 assert!(!e2.is_visible_at(e1));
584 assert!(e2.is_visible_at(e2));
585 assert!(e2.is_visible_at(e3));
586
587 assert!(!e3.is_visible_at(e1));
589 assert!(!e3.is_visible_at(e2));
590 assert!(e3.is_visible_at(e3));
591 }
592
593 #[test]
594 fn test_epoch_next() {
595 let e = EpochId::INITIAL;
596 assert_eq!(e.next(), EpochId::new(1));
597 assert_eq!(e.next().next(), EpochId::new(2));
598 }
599
600 #[test]
601 fn test_conversions() {
602 let node_id: NodeId = 42u64.into();
604 let raw: u64 = node_id.into();
605 assert_eq!(raw, 42);
606
607 let edge_id: EdgeId = 100u64.into();
609 let raw: u64 = edge_id.into();
610 assert_eq!(raw, 100);
611
612 let tx_id: TransactionId = 1u64.into();
614 let raw: u64 = tx_id.into();
615 assert_eq!(raw, 1);
616
617 let epoch_id: EpochId = 5u64.into();
619 let raw: u64 = epoch_id.into();
620 assert_eq!(raw, 5);
621 }
622}