• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::ops;
2 
3 use crate::document::Document;
4 use crate::key::Key;
5 use crate::table::TableKeyValue;
6 use crate::{value, InlineTable, InternalString, Item, Table, Value};
7 
8 // copied from
9 // https://github.com/serde-rs/json/blob/master/src/value/index.rs
10 
11 pub trait Index: crate::private::Sealed {
12     #[doc(hidden)]
index<'v>(&self, val: &'v Item) -> Option<&'v Item>13     fn index<'v>(&self, val: &'v Item) -> Option<&'v Item>;
14     #[doc(hidden)]
index_mut<'v>(&self, val: &'v mut Item) -> Option<&'v mut Item>15     fn index_mut<'v>(&self, val: &'v mut Item) -> Option<&'v mut Item>;
16 }
17 
18 impl Index for usize {
index<'v>(&self, v: &'v Item) -> Option<&'v Item>19     fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
20         match *v {
21             Item::ArrayOfTables(ref aot) => aot.values.get(*self),
22             Item::Value(ref a) if a.is_array() => a.as_array().and_then(|a| a.values.get(*self)),
23             _ => None,
24         }
25     }
index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item>26     fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
27         match *v {
28             Item::ArrayOfTables(ref mut vec) => vec.values.get_mut(*self),
29             Item::Value(ref mut a) => a.as_array_mut().and_then(|a| a.values.get_mut(*self)),
30             _ => None,
31         }
32     }
33 }
34 
35 impl Index for str {
index<'v>(&self, v: &'v Item) -> Option<&'v Item>36     fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
37         match *v {
38             Item::Table(ref t) => t.get(self),
39             Item::Value(ref v) => v
40                 .as_inline_table()
41                 .and_then(|t| t.items.get(self))
42                 .and_then(|kv| {
43                     if !kv.value.is_none() {
44                         Some(&kv.value)
45                     } else {
46                         None
47                     }
48                 }),
49             _ => None,
50         }
51     }
index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item>52     fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
53         if let Item::None = *v {
54             let mut t = InlineTable::default();
55             t.items.insert(
56                 InternalString::from(self),
57                 TableKeyValue::new(Key::new(self), Item::None),
58             );
59             *v = value(Value::InlineTable(t));
60         }
61         match *v {
62             Item::Table(ref mut t) => Some(t.entry(self).or_insert(Item::None)),
63             Item::Value(ref mut v) => v.as_inline_table_mut().map(|t| {
64                 &mut t
65                     .items
66                     .entry(InternalString::from(self))
67                     .or_insert_with(|| TableKeyValue::new(Key::new(self), Item::None))
68                     .value
69             }),
70             _ => None,
71         }
72     }
73 }
74 
75 impl Index for String {
index<'v>(&self, v: &'v Item) -> Option<&'v Item>76     fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
77         self[..].index(v)
78     }
index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item>79     fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
80         self[..].index_mut(v)
81     }
82 }
83 
84 impl<'a, T: ?Sized> Index for &'a T
85 where
86     T: Index,
87 {
index<'v>(&self, v: &'v Item) -> Option<&'v Item>88     fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
89         (**self).index(v)
90     }
index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item>91     fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
92         (**self).index_mut(v)
93     }
94 }
95 
96 impl<I> ops::Index<I> for Item
97 where
98     I: Index,
99 {
100     type Output = Item;
101 
index(&self, index: I) -> &Item102     fn index(&self, index: I) -> &Item {
103         index.index(self).expect("index not found")
104     }
105 }
106 
107 impl<I> ops::IndexMut<I> for Item
108 where
109     I: Index,
110 {
index_mut(&mut self, index: I) -> &mut Item111     fn index_mut(&mut self, index: I) -> &mut Item {
112         index.index_mut(self).expect("index not found")
113     }
114 }
115 
116 impl<'s> ops::Index<&'s str> for Table {
117     type Output = Item;
118 
index(&self, key: &'s str) -> &Item119     fn index(&self, key: &'s str) -> &Item {
120         self.get(key).expect("index not found")
121     }
122 }
123 
124 impl<'s> ops::IndexMut<&'s str> for Table {
index_mut(&mut self, key: &'s str) -> &mut Item125     fn index_mut(&mut self, key: &'s str) -> &mut Item {
126         self.entry(key).or_insert(Item::None)
127     }
128 }
129 
130 impl<'s> ops::Index<&'s str> for InlineTable {
131     type Output = Value;
132 
index(&self, key: &'s str) -> &Value133     fn index(&self, key: &'s str) -> &Value {
134         self.get(key).expect("index not found")
135     }
136 }
137 
138 impl<'s> ops::IndexMut<&'s str> for InlineTable {
index_mut(&mut self, key: &'s str) -> &mut Value139     fn index_mut(&mut self, key: &'s str) -> &mut Value {
140         self.get_mut(key).expect("index not found")
141     }
142 }
143 
144 impl<'s> ops::Index<&'s str> for Document {
145     type Output = Item;
146 
index(&self, key: &'s str) -> &Item147     fn index(&self, key: &'s str) -> &Item {
148         self.root.index(key)
149     }
150 }
151 
152 impl<'s> ops::IndexMut<&'s str> for Document {
index_mut(&mut self, key: &'s str) -> &mut Item153     fn index_mut(&mut self, key: &'s str) -> &mut Item {
154         self.root.index_mut(key)
155     }
156 }
157