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 TxId(pub u64);
150
151impl TxId {
152 pub const INVALID: Self = Self(0);
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 != 0
185 }
186}
187
188impl fmt::Debug for TxId {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 if self.is_valid() {
191 write!(f, "TxId({})", self.0)
192 } else {
193 write!(f, "TxId(INVALID)")
194 }
195 }
196}
197
198impl fmt::Display for TxId {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 write!(f, "{}", self.0)
201 }
202}
203
204impl From<u64> for TxId {
205 fn from(id: u64) -> Self {
206 Self(id)
207 }
208}
209
210impl From<TxId> for u64 {
211 fn from(id: TxId) -> 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 #[inline]
231 #[must_use]
232 pub const fn new(id: u64) -> Self {
233 Self(id)
234 }
235
236 #[inline]
238 #[must_use]
239 pub const fn as_u64(&self) -> u64 {
240 self.0
241 }
242
243 #[inline]
245 #[must_use]
246 pub const fn next(&self) -> Self {
247 Self(self.0 + 1)
248 }
249
250 #[inline]
254 #[must_use]
255 pub const fn is_visible_at(&self, viewing_epoch: Self) -> bool {
256 self.0 <= viewing_epoch.0
257 }
258}
259
260impl fmt::Debug for EpochId {
261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262 write!(f, "EpochId({})", self.0)
263 }
264}
265
266impl fmt::Display for EpochId {
267 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
268 write!(f, "{}", self.0)
269 }
270}
271
272impl From<u64> for EpochId {
273 fn from(id: u64) -> Self {
274 Self(id)
275 }
276}
277
278impl From<EpochId> for u64 {
279 fn from(id: EpochId) -> Self {
280 id.0
281 }
282}
283
284#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
289#[repr(transparent)]
290pub struct LabelId(pub u32);
291
292impl LabelId {
293 pub const INVALID: Self = Self(u32::MAX);
295
296 #[inline]
298 #[must_use]
299 pub const fn new(id: u32) -> Self {
300 Self(id)
301 }
302
303 #[inline]
305 #[must_use]
306 pub const fn as_u32(&self) -> u32 {
307 self.0
308 }
309
310 #[inline]
312 #[must_use]
313 pub const fn is_valid(&self) -> bool {
314 self.0 != u32::MAX
315 }
316}
317
318impl fmt::Debug for LabelId {
319 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
320 if self.is_valid() {
321 write!(f, "LabelId({})", self.0)
322 } else {
323 write!(f, "LabelId(INVALID)")
324 }
325 }
326}
327
328impl fmt::Display for LabelId {
329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330 write!(f, "{}", self.0)
331 }
332}
333
334impl From<u32> for LabelId {
335 fn from(id: u32) -> Self {
336 Self(id)
337 }
338}
339
340impl From<LabelId> for u32 {
341 fn from(id: LabelId) -> Self {
342 id.0
343 }
344}
345
346#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
351#[repr(transparent)]
352pub struct PropertyKeyId(pub u32);
353
354impl PropertyKeyId {
355 pub const INVALID: Self = Self(u32::MAX);
357
358 #[inline]
360 #[must_use]
361 pub const fn new(id: u32) -> Self {
362 Self(id)
363 }
364
365 #[inline]
367 #[must_use]
368 pub const fn as_u32(&self) -> u32 {
369 self.0
370 }
371
372 #[inline]
374 #[must_use]
375 pub const fn is_valid(&self) -> bool {
376 self.0 != u32::MAX
377 }
378}
379
380impl fmt::Debug for PropertyKeyId {
381 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382 if self.is_valid() {
383 write!(f, "PropertyKeyId({})", self.0)
384 } else {
385 write!(f, "PropertyKeyId(INVALID)")
386 }
387 }
388}
389
390impl fmt::Display for PropertyKeyId {
391 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392 write!(f, "{}", self.0)
393 }
394}
395
396impl From<u32> for PropertyKeyId {
397 fn from(id: u32) -> Self {
398 Self(id)
399 }
400}
401
402impl From<PropertyKeyId> for u32 {
403 fn from(id: PropertyKeyId) -> Self {
404 id.0
405 }
406}
407
408#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
413#[repr(transparent)]
414pub struct EdgeTypeId(pub u32);
415
416impl EdgeTypeId {
417 pub const INVALID: Self = Self(u32::MAX);
419
420 #[inline]
422 #[must_use]
423 pub const fn new(id: u32) -> Self {
424 Self(id)
425 }
426
427 #[inline]
429 #[must_use]
430 pub const fn as_u32(&self) -> u32 {
431 self.0
432 }
433
434 #[inline]
436 #[must_use]
437 pub const fn is_valid(&self) -> bool {
438 self.0 != u32::MAX
439 }
440}
441
442impl fmt::Debug for EdgeTypeId {
443 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
444 if self.is_valid() {
445 write!(f, "EdgeTypeId({})", self.0)
446 } else {
447 write!(f, "EdgeTypeId(INVALID)")
448 }
449 }
450}
451
452impl fmt::Display for EdgeTypeId {
453 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454 write!(f, "{}", self.0)
455 }
456}
457
458impl From<u32> for EdgeTypeId {
459 fn from(id: u32) -> Self {
460 Self(id)
461 }
462}
463
464impl From<EdgeTypeId> for u32 {
465 fn from(id: EdgeTypeId) -> Self {
466 id.0
467 }
468}
469
470#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
472#[repr(transparent)]
473pub struct IndexId(pub u32);
474
475impl IndexId {
476 pub const INVALID: Self = Self(u32::MAX);
478
479 #[inline]
481 #[must_use]
482 pub const fn new(id: u32) -> Self {
483 Self(id)
484 }
485
486 #[inline]
488 #[must_use]
489 pub const fn as_u32(&self) -> u32 {
490 self.0
491 }
492
493 #[inline]
495 #[must_use]
496 pub const fn is_valid(&self) -> bool {
497 self.0 != u32::MAX
498 }
499}
500
501impl fmt::Debug for IndexId {
502 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
503 if self.is_valid() {
504 write!(f, "IndexId({})", self.0)
505 } else {
506 write!(f, "IndexId(INVALID)")
507 }
508 }
509}
510
511impl fmt::Display for IndexId {
512 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
513 write!(f, "{}", self.0)
514 }
515}
516
517impl From<u32> for IndexId {
518 fn from(id: u32) -> Self {
519 Self(id)
520 }
521}
522
523impl From<IndexId> for u32 {
524 fn from(id: IndexId) -> Self {
525 id.0
526 }
527}
528
529#[cfg(test)]
530mod tests {
531 use super::*;
532
533 #[test]
534 fn test_node_id_basic() {
535 let id = NodeId::new(42);
536 assert_eq!(id.as_u64(), 42);
537 assert!(id.is_valid());
538 assert!(!NodeId::INVALID.is_valid());
539 }
540
541 #[test]
542 fn test_node_id_ordering() {
543 let id1 = NodeId::new(1);
544 let id2 = NodeId::new(2);
545 assert!(id1 < id2);
546 }
547
548 #[test]
549 fn test_edge_id_basic() {
550 let id = EdgeId::new(100);
551 assert_eq!(id.as_u64(), 100);
552 assert!(id.is_valid());
553 assert!(!EdgeId::INVALID.is_valid());
554 }
555
556 #[test]
557 fn test_tx_id_basic() {
558 let id = TxId::new(1);
559 assert!(id.is_valid());
560 assert!(!TxId::INVALID.is_valid());
561 assert_eq!(id.next(), TxId::new(2));
562 }
563
564 #[test]
565 fn test_epoch_visibility() {
566 let e1 = EpochId::new(1);
567 let e2 = EpochId::new(2);
568 let e3 = EpochId::new(3);
569
570 assert!(e1.is_visible_at(e2));
572 assert!(e1.is_visible_at(e3));
573
574 assert!(!e2.is_visible_at(e1));
576 assert!(e2.is_visible_at(e2));
577 assert!(e2.is_visible_at(e3));
578
579 assert!(!e3.is_visible_at(e1));
581 assert!(!e3.is_visible_at(e2));
582 assert!(e3.is_visible_at(e3));
583 }
584
585 #[test]
586 fn test_epoch_next() {
587 let e = EpochId::INITIAL;
588 assert_eq!(e.next(), EpochId::new(1));
589 assert_eq!(e.next().next(), EpochId::new(2));
590 }
591
592 #[test]
593 fn test_conversions() {
594 let node_id: NodeId = 42u64.into();
596 let raw: u64 = node_id.into();
597 assert_eq!(raw, 42);
598
599 let edge_id: EdgeId = 100u64.into();
601 let raw: u64 = edge_id.into();
602 assert_eq!(raw, 100);
603
604 let tx_id: TxId = 1u64.into();
606 let raw: u64 = tx_id.into();
607 assert_eq!(raw, 1);
608
609 let epoch_id: EpochId = 5u64.into();
611 let raw: u64 = epoch_id.into();
612 assert_eq!(raw, 5);
613 }
614}