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