1use crate::{path, Path};
7use std::collections::BTreeMap;
8
9#[derive(Debug, Clone)]
32pub struct PathTrie<T> {
33 value: Option<T>,
34 children: BTreeMap<String, PathTrie<T>>,
35}
36
37impl<T> Default for PathTrie<T> {
38 fn default() -> Self {
39 Self {
40 value: None,
41 children: BTreeMap::new(),
42 }
43 }
44}
45
46impl<T> PathTrie<T> {
47 pub fn new() -> Self {
49 Self::default()
50 }
51
52 fn get_or_create_node(&mut self, path: &Path) -> &mut PathTrie<T> {
54 let mut current = self;
55 for component in path.iter() {
56 current = current.children.entry(component.to_string()).or_default();
57 }
58 current
59 }
60
61 fn get_node(&self, path: &Path) -> Option<&PathTrie<T>> {
63 let mut current = self;
64 for component in path.iter() {
65 current = current.children.get(component)?;
66 }
67 Some(current)
68 }
69
70 fn get_node_mut(&mut self, path: &Path) -> Option<&mut PathTrie<T>> {
72 let mut current = self;
73 for component in path.iter() {
74 current = current.children.get_mut(component)?;
75 }
76 Some(current)
77 }
78
79 pub fn insert(&mut self, path: &Path, value: T) -> Option<T> {
81 let node = self.get_or_create_node(path);
82 node.value.replace(value)
83 }
84
85 pub fn remove(&mut self, path: &Path) -> Option<T> {
87 self.get_node_mut(path)?.value.take()
88 }
89
90 pub fn remove_subtree(&mut self, path: &Path) -> Option<PathTrie<T>> {
92 if path.is_empty() {
93 let old = std::mem::take(self);
94 if old.value.is_some() || !old.children.is_empty() {
95 Some(old)
96 } else {
97 None
98 }
99 } else {
100 let parent_path = path.slice(0, path.len() - 1);
101 let child_name = &path[path.len() - 1];
102 let parent = self.get_node_mut(&parent_path)?;
103 parent.children.remove(child_name)
104 }
105 }
106
107 pub fn get(&self, path: &Path) -> Option<&T> {
109 self.get_node(path)?.value.as_ref()
110 }
111
112 pub fn get_mut(&mut self, path: &Path) -> Option<&mut T> {
114 self.get_node_mut(path)?.value.as_mut()
115 }
116
117 pub fn get_subtrie(&self, path: &Path) -> Option<&PathTrie<T>> {
119 self.get_node(path)
120 }
121
122 pub fn get_subtrie_mut(&mut self, path: &Path) -> Option<&mut PathTrie<T>> {
124 self.get_node_mut(path)
125 }
126
127 pub fn contains_value(&self, path: &Path) -> bool {
129 self.get(path).is_some()
130 }
131
132 pub fn len(&self) -> usize {
134 let self_count = if self.value.is_some() { 1 } else { 0 };
135 let children_count: usize = self.children.values().map(|child| child.len()).sum();
136 self_count + children_count
137 }
138
139 pub fn is_empty(&self) -> bool {
141 self.value.is_none() && self.children.values().all(|c| c.is_empty())
142 }
143
144 pub fn find_ancestor(&self, path: &Path) -> Option<(&T, Path)> {
147 let mut current = self;
148 let mut last_value: Option<&T> = self.value.as_ref();
149 let mut last_depth: usize = 0;
150
151 for (depth, component) in path.iter().enumerate() {
152 match current.children.get(component) {
153 Some(child) => {
154 current = child;
155 if child.value.is_some() {
156 last_value = child.value.as_ref();
157 last_depth = depth + 1;
158 }
159 }
160 None => break,
161 }
162 }
163
164 last_value.map(|v| {
165 let suffix = path.slice(last_depth, path.len());
166 (v, suffix)
167 })
168 }
169
170 pub fn find_ancestor_mut(&mut self, path: &Path) -> Option<(&mut T, Path)> {
173 let depth = {
175 let mut current = &*self;
176 let mut last_depth: usize = if self.value.is_some() { 0 } else { usize::MAX };
177
178 for (d, component) in path.iter().enumerate() {
179 match current.children.get(component) {
180 Some(child) => {
181 current = child;
182 if child.value.is_some() {
183 last_depth = d + 1;
184 }
185 }
186 None => break,
187 }
188 }
189
190 if last_depth == usize::MAX {
191 return None;
192 }
193 last_depth
194 };
195
196 let target_path = path.slice(0, depth);
198 let suffix = path.slice(depth, path.len());
199
200 self.get_mut(&target_path).map(|v| (v, suffix))
201 }
202
203 pub fn iter(&self) -> PathTrieIter<'_, T> {
205 PathTrieIter::new(self)
206 }
207}
208
209pub struct PathTrieIter<'a, T> {
211 stack: Vec<(Path, &'a PathTrie<T>)>,
212}
213
214impl<'a, T> PathTrieIter<'a, T> {
215 fn new(trie: &'a PathTrie<T>) -> Self {
216 Self {
217 stack: vec![(path!(""), trie)],
218 }
219 }
220}
221
222impl<'a, T> Iterator for PathTrieIter<'a, T> {
223 type Item = (Path, &'a T);
224
225 fn next(&mut self) -> Option<Self::Item> {
226 while let Some((path, node)) = self.stack.pop() {
227 for (name, child) in node.children.iter().rev() {
229 let child_path = if path.is_empty() {
232 Path::from_validated_components(vec![name.clone()])
233 } else {
234 let mut c: Vec<String> = path.iter().map(str::to_string).collect();
235 c.push(name.clone());
236 Path::from_validated_components(c)
237 };
238 self.stack.push((child_path, child));
239 }
240
241 if let Some(ref value) = node.value {
243 return Some((path, value));
244 }
245 }
246 None
247 }
248}
249
250#[cfg(test)]
251mod tests {
252 use super::*;
253 use crate::path;
254
255 #[test]
256 fn new_trie_is_empty() {
257 let trie: PathTrie<i32> = PathTrie::new();
258 assert!(trie.is_empty());
259 assert_eq!(trie.len(), 0);
260 }
261
262 #[test]
263 fn insert_and_get() {
264 let mut trie: PathTrie<i32> = PathTrie::new();
265 trie.insert(&path!("a/b"), 42);
266
267 assert_eq!(trie.get(&path!("a/b")), Some(&42));
268 assert_eq!(trie.get(&path!("a")), None);
269 assert_eq!(trie.get(&path!("a/b/c")), None);
270 }
271
272 #[test]
273 fn insert_returns_previous() {
274 let mut trie: PathTrie<i32> = PathTrie::new();
275 assert_eq!(trie.insert(&path!("a"), 1), None);
276 assert_eq!(trie.insert(&path!("a"), 2), Some(1));
277 assert_eq!(trie.get(&path!("a")), Some(&2));
278 }
279
280 #[test]
281 fn remove_returns_value() {
282 let mut trie: PathTrie<i32> = PathTrie::new();
283 trie.insert(&path!("a/b"), 42);
284
285 assert_eq!(trie.remove(&path!("a/b")), Some(42));
286 assert_eq!(trie.get(&path!("a/b")), None);
287 }
288
289 #[test]
290 fn remove_keeps_children() {
291 let mut trie: PathTrie<i32> = PathTrie::new();
292 trie.insert(&path!("a"), 1);
293 trie.insert(&path!("a/b"), 2);
294
295 trie.remove(&path!("a"));
296
297 assert_eq!(trie.get(&path!("a")), None);
298 assert_eq!(trie.get(&path!("a/b")), Some(&2));
299 }
300
301 #[test]
302 fn remove_subtree() {
303 let mut trie: PathTrie<i32> = PathTrie::new();
304 trie.insert(&path!("a"), 1);
305 trie.insert(&path!("a/b"), 2);
306 trie.insert(&path!("c"), 3);
307
308 let subtree = trie.remove_subtree(&path!("a")).unwrap();
309
310 assert_eq!(subtree.get(&path!("")), Some(&1));
311 assert_eq!(subtree.get(&path!("b")), Some(&2));
312 assert_eq!(trie.get(&path!("a")), None);
313 assert_eq!(trie.get(&path!("a/b")), None);
314 assert_eq!(trie.get(&path!("c")), Some(&3));
315 }
316
317 #[test]
318 fn remove_subtree_at_root() {
319 let mut trie: PathTrie<i32> = PathTrie::new();
320 trie.insert(&path!("a"), 1);
321 trie.insert(&path!("b"), 2);
322
323 let subtree = trie.remove_subtree(&path!("")).unwrap();
324
325 assert!(trie.is_empty());
326 assert_eq!(subtree.get(&path!("a")), Some(&1));
327 assert_eq!(subtree.get(&path!("b")), Some(&2));
328 }
329
330 #[test]
331 fn remove_subtree_nonexistent() {
332 let mut trie: PathTrie<i32> = PathTrie::new();
333 trie.insert(&path!("a"), 1);
334
335 assert!(trie.remove_subtree(&path!("nonexistent")).is_none());
336 }
337
338 #[test]
339 fn get_mut() {
340 let mut trie: PathTrie<i32> = PathTrie::new();
341 trie.insert(&path!("a"), 1);
342
343 *trie.get_mut(&path!("a")).unwrap() = 42;
344
345 assert_eq!(trie.get(&path!("a")), Some(&42));
346 }
347
348 #[test]
349 fn contains_value() {
350 let mut trie: PathTrie<i32> = PathTrie::new();
351 trie.insert(&path!("a/b"), 1);
352
353 assert!(trie.contains_value(&path!("a/b")));
354 assert!(!trie.contains_value(&path!("a")));
355 assert!(!trie.contains_value(&path!("nonexistent")));
356 }
357
358 #[test]
359 fn len_and_is_empty() {
360 let mut trie: PathTrie<i32> = PathTrie::new();
361 assert!(trie.is_empty());
362 assert_eq!(trie.len(), 0);
363
364 trie.insert(&path!("a"), 1);
365 assert!(!trie.is_empty());
366 assert_eq!(trie.len(), 1);
367
368 trie.insert(&path!("a/b"), 2);
369 assert_eq!(trie.len(), 2);
370
371 trie.insert(&path!("c"), 3);
372 assert_eq!(trie.len(), 3);
373 }
374
375 #[test]
376 fn find_ancestor_basic() {
377 let mut trie: PathTrie<&str> = PathTrie::new();
378 trie.insert(&path!("data"), "data_store");
379
380 let (value, suffix) = trie.find_ancestor(&path!("data/users/1")).unwrap();
381 assert_eq!(*value, "data_store");
382 assert_eq!(suffix, path!("users/1"));
383 }
384
385 #[test]
386 fn find_ancestor_deeper_wins() {
387 let mut trie: PathTrie<&str> = PathTrie::new();
388 trie.insert(&path!("data"), "data_store");
389 trie.insert(&path!("data/cache"), "cache_store");
390
391 let (value, suffix) = trie.find_ancestor(&path!("data/cache/hot")).unwrap();
393 assert_eq!(*value, "cache_store");
394 assert_eq!(suffix, path!("hot"));
395
396 let (value, suffix) = trie.find_ancestor(&path!("data/users/1")).unwrap();
398 assert_eq!(*value, "data_store");
399 assert_eq!(suffix, path!("users/1"));
400 }
401
402 #[test]
403 fn find_ancestor_at_root() {
404 let mut trie: PathTrie<&str> = PathTrie::new();
405 trie.insert(&path!(""), "root_store");
406
407 let (value, suffix) = trie.find_ancestor(&path!("any/path")).unwrap();
408 assert_eq!(*value, "root_store");
409 assert_eq!(suffix, path!("any/path"));
410 }
411
412 #[test]
413 fn find_ancestor_no_match() {
414 let mut trie: PathTrie<&str> = PathTrie::new();
415 trie.insert(&path!("data"), "data_store");
416
417 assert!(trie.find_ancestor(&path!("other/path")).is_none());
418 }
419
420 #[test]
421 fn find_ancestor_exact_match() {
422 let mut trie: PathTrie<&str> = PathTrie::new();
423 trie.insert(&path!("data"), "data_store");
424
425 let (value, suffix) = trie.find_ancestor(&path!("data")).unwrap();
426 assert_eq!(*value, "data_store");
427 assert!(suffix.is_empty());
428 }
429
430 #[test]
431 fn find_ancestor_mut() {
432 let mut trie: PathTrie<i32> = PathTrie::new();
433 trie.insert(&path!("a"), 1);
434 trie.insert(&path!("a/b"), 2);
435
436 let (value, suffix) = trie.find_ancestor_mut(&path!("a/b/c")).unwrap();
437 assert_eq!(*value, 2);
438 assert_eq!(suffix, path!("c"));
439
440 *value = 42;
442 assert_eq!(trie.get(&path!("a/b")), Some(&42));
443 }
444
445 #[test]
446 fn find_ancestor_mut_no_match() {
447 let mut trie: PathTrie<i32> = PathTrie::new();
448 trie.insert(&path!("a"), 1);
449
450 assert!(trie.find_ancestor_mut(&path!("b/c")).is_none());
451 }
452
453 #[test]
454 fn iter_all_values() {
455 let mut trie: PathTrie<i32> = PathTrie::new();
456 trie.insert(&path!("a"), 1);
457 trie.insert(&path!("b"), 2);
458 trie.insert(&path!("a/c"), 3);
459
460 let mut items: Vec<_> = trie.iter().collect();
461 items.sort_by_key(|a| a.0.to_string());
462
463 assert_eq!(items.len(), 3);
464 assert_eq!(items[0], (path!("a"), &1));
465 assert_eq!(items[1], (path!("a/c"), &3));
466 assert_eq!(items[2], (path!("b"), &2));
467 }
468
469 #[test]
470 fn iter_empty() {
471 let trie: PathTrie<i32> = PathTrie::new();
472 assert_eq!(trie.iter().count(), 0);
473 }
474
475 #[test]
476 fn iter_root_value() {
477 let mut trie: PathTrie<i32> = PathTrie::new();
478 trie.insert(&path!(""), 42);
479
480 let items: Vec<_> = trie.iter().collect();
481 assert_eq!(items.len(), 1);
482 assert_eq!(items[0], (path!(""), &42));
483 }
484
485 #[test]
486 fn get_subtrie() {
487 let mut trie: PathTrie<i32> = PathTrie::new();
488 trie.insert(&path!("a/b"), 1);
489 trie.insert(&path!("a/c"), 2);
490
491 let subtrie = trie.get_subtrie(&path!("a")).unwrap();
492 assert_eq!(subtrie.get(&path!("b")), Some(&1));
493 assert_eq!(subtrie.get(&path!("c")), Some(&2));
494 }
495
496 #[test]
497 fn get_subtrie_nonexistent() {
498 let trie: PathTrie<i32> = PathTrie::new();
499 assert!(trie.get_subtrie(&path!("nonexistent")).is_none());
500 }
501
502 #[test]
503 fn clone_trie() {
504 let mut trie: PathTrie<i32> = PathTrie::new();
505 trie.insert(&path!("a"), 1);
506
507 let cloned = trie.clone();
508 assert_eq!(cloned.get(&path!("a")), Some(&1));
509 }
510
511 #[test]
512 fn default_trie() {
513 let trie: PathTrie<i32> = PathTrie::default();
514 assert!(trie.is_empty());
515 }
516
517 #[test]
518 fn debug_trie() {
519 let mut trie: PathTrie<i32> = PathTrie::new();
520 trie.insert(&path!("a"), 1);
521 let debug = format!("{:?}", trie);
522 assert!(debug.contains("PathTrie"));
523 }
524
525 #[test]
526 fn insert_at_root() {
527 let mut trie: PathTrie<i32> = PathTrie::new();
528 trie.insert(&path!(""), 42);
529
530 assert_eq!(trie.get(&path!("")), Some(&42));
531 assert_eq!(trie.len(), 1);
532 }
533
534 #[test]
535 fn remove_at_root() {
536 let mut trie: PathTrie<i32> = PathTrie::new();
537 trie.insert(&path!(""), 42);
538
539 assert_eq!(trie.remove(&path!("")), Some(42));
540 assert!(trie.is_empty());
541 }
542
543 #[test]
544 fn get_subtrie_mut() {
545 let mut trie: PathTrie<i32> = PathTrie::new();
546 trie.insert(&path!("a/b"), 1);
547
548 let subtrie = trie.get_subtrie_mut(&path!("a")).unwrap();
549 subtrie.insert(&path!("c"), 2);
550
551 assert_eq!(trie.get(&path!("a/c")), Some(&2));
552 }
553
554 #[test]
555 fn remove_subtree_empty_trie() {
556 let mut trie: PathTrie<i32> = PathTrie::new();
557 assert!(trie.remove_subtree(&path!("")).is_none());
558 }
559
560 #[test]
561 fn is_empty_with_only_structure() {
562 let mut trie: PathTrie<i32> = PathTrie::new();
563 trie.insert(&path!("a/b/c"), 1);
564 trie.remove(&path!("a/b/c"));
565
566 assert!(trie.is_empty());
568 }
569}