1use smol_str::SmolStr;
2
3#[derive(Clone, Debug, PartialEq, Eq, Hash)]
9pub struct NodeKey {
10 pub label: SmolStr,
12 pub primary_key: SmolStr,
14}
15
16impl NodeKey {
17 pub fn new(label: impl Into<SmolStr>, primary_key: impl Into<SmolStr>) -> Self {
18 Self {
19 label: label.into(),
20 primary_key: primary_key.into(),
21 }
22 }
23}
24
25impl std::fmt::Display for NodeKey {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(f, "{}:{}", self.label, self.primary_key)
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn new_basic() {
37 let key = NodeKey::new("Function", "main");
38 assert_eq!(key.label, "Function");
39 assert_eq!(key.primary_key, "main");
40 }
41
42 #[test]
43 fn display_format() {
44 let key = NodeKey::new("Document", "invoice_123");
45 assert_eq!(format!("{key}"), "Document:invoice_123");
46 }
47
48 #[test]
49 fn equality() {
50 let a = NodeKey::new("Function", "main");
51 let b = NodeKey::new("Function", "main");
52 assert_eq!(a, b);
53 }
54
55 #[test]
56 fn different_labels_not_equal() {
57 let a = NodeKey::new("Function", "main");
58 let b = NodeKey::new("File", "main");
59 assert_ne!(a, b);
60 }
61
62 #[test]
63 fn hash_consistency() {
64 use std::collections::hash_map::DefaultHasher;
65 use std::hash::{Hash, Hasher};
66 let a = NodeKey::new("X", "y");
67 let b = NodeKey::new("X", "y");
68 let mut ha = DefaultHasher::new();
69 let mut hb = DefaultHasher::new();
70 a.hash(&mut ha);
71 b.hash(&mut hb);
72 assert_eq!(ha.finish(), hb.finish());
73 }
74
75 #[test]
76 fn clone() {
77 let a = NodeKey::new("A", "b");
78 let b = a.clone();
79 assert_eq!(a, b);
80 }
81}