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
use std::collections::HashMap;
use value::Value;

impl Value {
  pub fn get(&self, path: &str) -> &Value {
    let path_chunks = path.split(".");
    let mut ctx = self;
    for chunk in path_chunks {
      ctx = ctx.get_key(chunk);
    }
    ctx
  }

  fn get_key(&self, key: &str) -> &Value {
    match *self {
      Value::HashMap(ref h) => h.get(key).unwrap_or(&Value::None),
      _ => &Value::None,
    }
  }

  fn get_key_mut(&mut self, key: &str) -> Option<&mut Value> {
    match *self {
      Value::HashMap(ref mut h) => h.get_mut(key),
      _ => None,
    }
  }

  pub fn set(&mut self, path: &str, mut value: Value) {
    let mut chunks: Vec<_> = path.split(".").collect();
    if chunks.len() == 0 {
      return;
    }
    let key = chunks.remove(0);

    if chunks.len() != 0 {
      if let Some(ref mut next_value) = self.get_key_mut(key) {
        return next_value.set(&chunks.join("."), value);
      }
    }

    chunks.reverse();
    while let Some(chunk) = chunks.pop() {
      value = {
        match chunk.parse::<usize>() {
          Ok(i) => {
            let mut vec = Vec::new();
            vec.insert(i, value);
            Value::from(vec)
          }
          Err(_) => {
            let mut hash_map = HashMap::new();
            hash_map.insert(chunk.to_owned(), value);
            Value::from(hash_map)
          }
        }
      };
    }

    self.set_key(key, value);
  }

  fn set_key(&mut self, key: &str, value: Value) {
    match *self {
      Value::HashMap(ref mut h) => {
        h.insert(key.to_string(), value);
      }
      _ => (),
    }
  }
}