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