humphrey_json/
indexing.rs1use crate::Value;
4
5use std::ops;
6
7pub trait Index {
9 fn json_index<'v>(&self, v: &'v Value) -> Option<&'v Value>;
11 fn json_index_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
13}
14
15impl Index for usize {
16 fn json_index<'v>(&self, v: &'v Value) -> Option<&'v Value> {
17 match v {
18 Value::Array(a) => a.get(*self),
19 _ => None,
20 }
21 }
22
23 fn json_index_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
24 match v {
25 Value::Array(a) => a.get_mut(*self),
26 _ => None,
27 }
28 }
29}
30
31impl Index for &str {
32 fn json_index<'v>(&self, v: &'v Value) -> Option<&'v Value> {
33 match v {
34 Value::Object(o) => o.iter().find(|(k, _)| k == self).map(|(_, v)| v),
35 _ => None,
36 }
37 }
38
39 fn json_index_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
40 match v {
41 Value::Object(o) => {
42 if let Some(i) = o.iter().position(|(k, _)| k == self) {
43 Some(&mut o[i].1)
44 } else {
45 o.push((self.to_string(), Value::Null));
46 o.last_mut().map(|(_, v)| v)
47 }
48 }
49 _ => None,
50 }
51 }
52}
53
54impl Index for String {
55 fn json_index<'v>(&self, v: &'v Value) -> Option<&'v Value> {
56 self.as_str().json_index(v)
57 }
58
59 fn json_index_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
60 self.as_str().json_index_mut(v)
61 }
62}
63
64impl<T> ops::Index<T> for Value
65where
66 T: Index,
67{
68 type Output = Value;
69
70 fn index(&self, index: T) -> &Self::Output {
71 index.json_index(self).unwrap_or(&Value::Null)
72 }
73}
74
75impl<T> ops::IndexMut<T> for Value
76where
77 T: Index,
78{
79 fn index_mut(&mut self, index: T) -> &mut Self::Output {
80 index
81 .json_index_mut(self)
82 .expect("Cannot get mutable index")
83 }
84}