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