1#[macro_use]
2extern crate serde_json;
3
4use serde_json::{Value};
5
6#[derive(Debug)]
9pub struct ConfigStack {
10 path_sep: char,
11 configs: Vec<Value>,
12}
13
14#[derive(Debug, PartialEq)]
19pub enum Lookup {
20 Missing,
22 Found(Value),
24}
25
26impl ConfigStack {
27 pub fn new() -> ConfigStack {
28 ConfigStack { path_sep: '/', configs: vec![], }
29 }
30
31 pub fn with_path_sep(self, sep: char) -> ConfigStack {
32 ConfigStack {
33 path_sep: sep,
34 configs: self.configs,
35 }
36 }
37
38 pub fn push(mut self, config: Value) -> ConfigStack {
39 self.configs.push(config);
40 self
41 }
42
43 pub fn pop(mut self) -> Option<Value> {
44 self.configs.pop()
45 }
46
47 fn path_to_parts(&self, path: &str) -> Vec<String> {
48 let parts = path.trim_matches(self.path_sep).split(self.path_sep);
49 parts.map(|s| s.to_string()).collect()
50 }
51
52 pub fn get(&self, path: &str) -> Lookup {
53 self.get_parts(self.path_to_parts(path))
54 }
55
56 pub fn get_parts(&self, path_parts: Vec<String>) -> Lookup {
57 'outer: for i in 0..self.configs.len() {
58 let idx = self.configs.len() - i - 1;
59 let mut node = &self.configs[idx];
60
61 for part in path_parts.iter() {
62 match node.get(part) {
63 Some(subobj) => node = subobj,
64 None => {
65 if idx == 0 {
66 return Lookup::Missing;
67 }
68 continue 'outer;
69 },
70 }
71 }
72 return Lookup::Found(node.to_owned());
73 }
74 return Lookup::Missing;
75 }
76}
77
78
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_lookup() {
84 fn work() -> serde_json::Result<ConfigStack> {
85 let stack = ConfigStack::new();
86
87 let s1 = r#"{
88 "a": {
89 "b": {
90 "c": 1,
91 "d": [1, 2, 3]
92 },
93 "e": 1
94 }
95 }"#;
96 let v1: Value = serde_json::from_str(s1)?;
97
98 let s2 = r#"{
99 "a": {
100 "b": {
101 "c": 2
102 }
103 }
104 }"#;
105 let v2: Value = serde_json::from_str(s2)?;
106 Ok(stack.push(v1).push(v2))
107 }
108
109 match work() {
110 Ok(stack) => {
111 let expected: Value = json!(2);
112 assert_eq!(stack.get("a/b/c"), Lookup::Found(expected));
113 },
114 _ => assert!(false),
115 }
116 }
117}