Skip to main content

khive_fold/ordering/
has_id.rs

1//! HasId trait for candidates with stable UUID identifiers
2
3use uuid::Uuid;
4
5/// Trait for candidates with stable UUID identifiers.
6///
7/// Implementing this trait enables deterministic tie-breaking when
8/// candidates have equal scores.
9///
10/// # Contract
11///
12/// - `id()` MUST return the same value for the same logical entity
13/// - The UUID SHOULD be globally unique (use `Uuid::new_v4()` or similar)
14/// - The UUID MUST NOT change between calls for the same instance
15pub trait HasId {
16    /// Returns the stable UUID identifier for this candidate.
17    fn id(&self) -> Uuid;
18}
19
20impl HasId for Uuid {
21    #[inline]
22    fn id(&self) -> Uuid {
23        *self
24    }
25}
26
27impl HasId for (f64, Uuid) {
28    #[inline]
29    fn id(&self) -> Uuid {
30        self.1
31    }
32}
33
34impl HasId for (f32, Uuid) {
35    #[inline]
36    fn id(&self) -> Uuid {
37        self.1
38    }
39}
40
41impl<T: HasId> HasId for &T {
42    #[inline]
43    fn id(&self) -> Uuid {
44        (*self).id()
45    }
46}
47
48impl<T: HasId> HasId for &mut T {
49    #[inline]
50    fn id(&self) -> Uuid {
51        (**self).id()
52    }
53}
54
55impl<T: HasId> HasId for Box<T> {
56    #[inline]
57    fn id(&self) -> Uuid {
58        (**self).id()
59    }
60}
61
62impl<T: HasId> HasId for std::sync::Arc<T> {
63    #[inline]
64    fn id(&self) -> Uuid {
65        (**self).id()
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    struct Item {
74        id: Uuid,
75    }
76
77    impl HasId for Item {
78        fn id(&self) -> Uuid {
79            self.id
80        }
81    }
82
83    #[test]
84    fn test_uuid_has_id() {
85        let id = Uuid::new_v4();
86        assert_eq!(id.id(), id);
87    }
88
89    #[test]
90    fn test_ref_has_id() {
91        let item = Item { id: Uuid::new_v4() };
92        let r: &Item = &item;
93        assert_eq!(r.id(), item.id);
94    }
95
96    #[test]
97    fn test_box_has_id() {
98        let id = Uuid::new_v4();
99        let boxed: Box<Uuid> = Box::new(id);
100        assert_eq!(boxed.id(), id);
101    }
102
103    #[test]
104    fn test_arc_has_id() {
105        let id = Uuid::new_v4();
106        let arc = std::sync::Arc::new(id);
107        assert_eq!(arc.id(), id);
108    }
109
110    #[test]
111    fn test_tuple_f64_uuid() {
112        let id = Uuid::new_v4();
113        let t: (f64, Uuid) = (0.5, id);
114        assert_eq!(t.id(), id);
115    }
116}