rosrust/api/naming/
mapper.rs
1use super::path::{Buffer, Path, Slice};
2use std::collections::HashMap;
3
4pub struct Mapper {
5 children: HashMap<String, Mapper>,
6 value: Option<Buffer>,
7}
8
9impl Mapper {
10 pub fn new() -> Mapper {
11 Mapper {
12 children: HashMap::new(),
13 value: None,
14 }
15 }
16
17 pub fn add(&mut self, keys: &[String], value: Buffer) {
18 match keys.split_first() {
19 None => {
20 self.value = Some(value);
21 }
22 Some((key, child_keys)) => {
23 self.children
24 .entry(key.clone())
25 .or_insert_with(Mapper::new)
26 .add(child_keys, value);
27 }
28 }
29 }
30
31 pub fn translate(&self, keys: &[String]) -> Option<Slice> {
32 match keys.split_first() {
33 None => self.value.as_ref().map(Path::slice),
34 Some((key, child_keys)) => self.children.get(key).and_then(|v| v.translate(child_keys)),
35 }
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::super::path::{Buffer, Path};
42 use super::*;
43
44 static FAILED_TO_MAP: &str = "Failed to map";
45
46 #[test]
47 fn matches_existing_paths() {
48 let mut mapper = Mapper::new();
49 let src1 = "/foo/bar".parse::<Buffer>().expect(FAILED_TO_MAP);
50 let dst = "/a/b/c".parse::<Buffer>().expect(FAILED_TO_MAP);
51 mapper.add(src1.get(), dst);
52 let src2 = "/foo/ter".parse::<Buffer>().expect(FAILED_TO_MAP);
53 let dst = "/d/e/f".parse::<Buffer>().expect(FAILED_TO_MAP);
54 mapper.add(src2.get(), dst);
55 assert_eq!(
56 "/a/b/c",
57 format!("{}", mapper.translate(src1.get()).expect(FAILED_TO_MAP))
58 );
59 assert_eq!(
60 "/d/e/f",
61 format!("{}", mapper.translate(src2.get()).expect(FAILED_TO_MAP))
62 );
63 }
64
65 #[test]
66 fn allows_root_path() {
67 let mut mapper = Mapper::new();
68 let src1 = "/".parse::<Buffer>().expect(FAILED_TO_MAP);
69 let dst = "/a/b/c".parse::<Buffer>().expect(FAILED_TO_MAP);
70 mapper.add(src1.get(), dst);
71 let src2 = "/foo/ter".parse::<Buffer>().expect(FAILED_TO_MAP);
72 let dst = "/".parse::<Buffer>().expect(FAILED_TO_MAP);
73 mapper.add(src2.get(), dst);
74 assert_eq!(
75 "/a/b/c",
76 format!("{}", mapper.translate(src1.get()).expect(FAILED_TO_MAP))
77 );
78 assert_eq!(
79 "",
80 format!("{}", mapper.translate(src2.get()).expect(FAILED_TO_MAP))
81 );
82 }
83
84 #[test]
85 fn fails_missing_paths() {
86 let mut mapper = Mapper::new();
87 let src1 = "/foo/bar".parse::<Buffer>().expect(FAILED_TO_MAP);
88 let dst = "/a/b/c".parse::<Buffer>().expect(FAILED_TO_MAP);
89 mapper.add(src1.get(), dst);
90 let src2 = "/foo/ter".parse::<Buffer>().expect(FAILED_TO_MAP);
91 let dst = "/d/e/f".parse::<Buffer>().expect(FAILED_TO_MAP);
92 mapper.add(src2.get(), dst);
93 let src3 = "/foo/bla".parse::<Buffer>().expect(FAILED_TO_MAP);
94 assert!(mapper.translate(src3.get()).is_none());
95 }
96
97 #[test]
98 fn allows_to_redefine() {
99 let mut mapper = Mapper::new();
100 let src = "/foo/bar".parse::<Buffer>().expect(FAILED_TO_MAP);
101 let dst1 = "/a/b/c".parse::<Buffer>().expect(FAILED_TO_MAP);
102 mapper.add(src.get(), dst1);
103 assert_eq!(
104 "/a/b/c",
105 format!("{}", mapper.translate(src.get()).expect(FAILED_TO_MAP))
106 );
107 let dst2 = "/d/e/f".parse::<Buffer>().expect(FAILED_TO_MAP);
108 mapper.add(src.get(), dst2);
109 assert_eq!(
110 "/d/e/f",
111 format!("{}", mapper.translate(src.get()).expect(FAILED_TO_MAP))
112 );
113 }
114}