Skip to main content

meshdb_core/
id.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3use uuid::Uuid;
4
5macro_rules! define_id {
6    ($name:ident) => {
7        #[derive(
8            Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
9        )]
10        #[repr(transparent)]
11        pub struct $name(Uuid);
12
13        impl $name {
14            pub fn new() -> Self {
15                Self(Uuid::now_v7())
16            }
17
18            pub fn from_uuid(uuid: Uuid) -> Self {
19                Self(uuid)
20            }
21
22            pub fn from_bytes(bytes: [u8; 16]) -> Self {
23                Self(Uuid::from_bytes(bytes))
24            }
25
26            pub fn as_uuid(&self) -> Uuid {
27                self.0
28            }
29
30            pub fn as_bytes(&self) -> &[u8; 16] {
31                self.0.as_bytes()
32            }
33        }
34
35        impl Default for $name {
36            fn default() -> Self {
37                Self::new()
38            }
39        }
40
41        impl fmt::Display for $name {
42            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43                write!(f, "{}", self.0)
44            }
45        }
46    };
47}
48
49define_id!(NodeId);
50define_id!(EdgeId);
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn ids_are_unique_and_ordered() {
58        let a = NodeId::new();
59        let b = NodeId::new();
60        assert_ne!(a, b);
61        assert!(a < b, "UUIDv7 should produce monotonically ordered IDs");
62    }
63
64    #[test]
65    fn node_and_edge_ids_are_distinct_types() {
66        let n = NodeId::new();
67        let e = EdgeId::from_uuid(n.as_uuid());
68        assert_eq!(n.as_uuid(), e.as_uuid());
69    }
70}