toml_scaffold/
field_path.rs1#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct FieldPath(Vec<String>);
7
8impl FieldPath {
9 pub fn new() -> Self {
11 Self(Vec::new())
12 }
13
14 pub fn from_vec(segments: Vec<String>) -> Self {
16 Self(segments)
17 }
18
19 pub fn push(&mut self, segment: String) {
21 self.0.push(segment);
22 }
23
24 pub fn child(&self, segment: String) -> Self {
26 let mut path = self.clone();
27 path.push(segment);
28 path
29 }
30
31 pub fn len(&self) -> usize {
33 self.0.len()
34 }
35
36 pub fn starts_with(&self, other: &FieldPath) -> bool {
38 self.0.starts_with(&other.0)
39 }
40
41 pub fn get(&self, index: usize) -> Option<&String> {
43 self.0.get(index)
44 }
45
46 pub fn as_dotted_key(&self) -> String {
48 use toml_writer::TomlWrite;
49
50 let mut result = String::new();
51 for (i, segment) in self.0.iter().enumerate() {
52 if i > 0 {
53 result.push('.');
54 }
55 let _ = result.key(segment.as_str());
56 }
57 result
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use std::collections::HashMap;
65
66 #[test]
67 fn test_new() {
68 let path = FieldPath::new();
69 assert_eq!(path.len(), 0);
70 assert_eq!(path.as_dotted_key(), "");
71 }
72
73 #[test]
74 fn test_from_vec() {
75 let path = FieldPath::from_vec(vec!["a".to_string(), "b".to_string()]);
76 assert_eq!(path.len(), 2);
77 assert_eq!(path.as_dotted_key(), "a.b");
78 }
79
80 #[test]
81 fn test_push() {
82 let mut path = FieldPath::new();
83 path.push("first".to_string());
84 path.push("second".to_string());
85 assert_eq!(path.len(), 2);
86 assert_eq!(path.as_dotted_key(), "first.second");
87 }
88
89 #[test]
90 fn test_child() {
91 let parent = FieldPath::from_vec(vec!["parent".to_string()]);
92 let child = parent.child("child".to_string());
93 assert_eq!(parent.len(), 1);
94 assert_eq!(child.len(), 2);
95 assert_eq!(child.as_dotted_key(), "parent.child");
96 }
97
98 #[test]
99 fn test_starts_with() {
100 let parent = FieldPath::from_vec(vec!["a".to_string(), "b".to_string()]);
101 let child = FieldPath::from_vec(vec!["a".to_string(), "b".to_string(), "c".to_string()]);
102 let other = FieldPath::from_vec(vec!["x".to_string()]);
103
104 assert!(child.starts_with(&parent));
105 assert!(!child.starts_with(&other));
106 assert!(parent.starts_with(&parent));
107 }
108
109 #[test]
110 fn test_get() {
111 let path = FieldPath::from_vec(vec!["a".to_string(), "b".to_string(), "c".to_string()]);
112 assert_eq!(path.get(0), Some(&"a".to_string()));
113 assert_eq!(path.get(1), Some(&"b".to_string()));
114 assert_eq!(path.get(2), Some(&"c".to_string()));
115 assert_eq!(path.get(3), None);
116 }
117
118 #[test]
119 fn test_field_with_dots() {
120 let path = FieldPath::from_vec(vec!["field.with.dots".to_string()]);
121 assert_eq!(path.len(), 1);
122 assert_eq!(path.as_dotted_key(), "\"field.with.dots\"");
123 }
124
125 #[test]
126 fn test_hash_map_key() {
127 let mut map = HashMap::new();
128 let path1 = FieldPath::from_vec(vec!["a".to_string(), "b".to_string()]);
129 let path2 = FieldPath::from_vec(vec!["a".to_string(), "b".to_string()]);
130 let path3 = FieldPath::from_vec(vec!["a".to_string(), "c".to_string()]);
131
132 map.insert(path1.clone(), "value1");
133 map.insert(path3, "value2");
134
135 assert_eq!(map.get(&path2), Some(&"value1"));
136 assert_eq!(map.len(), 2);
137 }
138}