1 use super::Value; 2 use crate::lib::*; 3 use crate::map::Map; 4 5 /// A type that can be used to index into a `serde_json::Value`. 6 /// 7 /// The [`get`] and [`get_mut`] methods of `Value` accept any type that 8 /// implements `Index`, as does the [square-bracket indexing operator]. This 9 /// trait is implemented for strings which are used as the index into a JSON 10 /// map, and for `usize` which is used as the index into a JSON array. 11 /// 12 /// [`get`]: ../enum.Value.html#method.get 13 /// [`get_mut`]: ../enum.Value.html#method.get_mut 14 /// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E 15 /// 16 /// This trait is sealed and cannot be implemented for types outside of 17 /// `serde_json`. 18 /// 19 /// # Examples 20 /// 21 /// ``` 22 /// # use serde_json::json; 23 /// # 24 /// let data = json!({ "inner": [1, 2, 3] }); 25 /// 26 /// // Data is a JSON map so it can be indexed with a string. 27 /// let inner = &data["inner"]; 28 /// 29 /// // Inner is a JSON array so it can be indexed with an integer. 30 /// let first = &inner[0]; 31 /// 32 /// assert_eq!(first, 1); 33 /// ``` 34 pub trait Index: private::Sealed { 35 /// Return None if the key is not already in the array or object. 36 #[doc(hidden)] index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>37 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; 38 39 /// Return None if the key is not already in the array or object. 40 #[doc(hidden)] index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>41 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; 42 43 /// Panic if array index out of bounds. If key is not already in the object, 44 /// insert it with a value of null. Panic if Value is a type that cannot be 45 /// indexed into, except if Value is null then it can be treated as an empty 46 /// object. 47 #[doc(hidden)] index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value48 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; 49 } 50 51 impl Index for usize { index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>52 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 53 match *v { 54 Value::Array(ref vec) => vec.get(*self), 55 _ => None, 56 } 57 } index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>58 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 59 match *v { 60 Value::Array(ref mut vec) => vec.get_mut(*self), 61 _ => None, 62 } 63 } index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value64 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 65 match *v { 66 Value::Array(ref mut vec) => { 67 let len = vec.len(); 68 vec.get_mut(*self).unwrap_or_else(|| { 69 panic!( 70 "cannot access index {} of JSON array of length {}", 71 self, len 72 ) 73 }) 74 } 75 _ => panic!("cannot access index {} of JSON {}", self, Type(v)), 76 } 77 } 78 } 79 80 impl Index for str { index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>81 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 82 match *v { 83 Value::Object(ref map) => map.get(self), 84 _ => None, 85 } 86 } index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>87 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 88 match *v { 89 Value::Object(ref mut map) => map.get_mut(self), 90 _ => None, 91 } 92 } index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value93 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 94 if let Value::Null = *v { 95 *v = Value::Object(Map::new()); 96 } 97 match *v { 98 Value::Object(ref mut map) => map.entry(self.to_owned()).or_insert(Value::Null), 99 _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), 100 } 101 } 102 } 103 104 impl Index for String { index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>105 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 106 self[..].index_into(v) 107 } index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>108 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 109 self[..].index_into_mut(v) 110 } index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value111 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 112 self[..].index_or_insert(v) 113 } 114 } 115 116 impl<'a, T> Index for &'a T 117 where 118 T: ?Sized + Index, 119 { index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>120 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 121 (**self).index_into(v) 122 } index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>123 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 124 (**self).index_into_mut(v) 125 } index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value126 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 127 (**self).index_or_insert(v) 128 } 129 } 130 131 // Prevent users from implementing the Index trait. 132 mod private { 133 pub trait Sealed {} 134 impl Sealed for usize {} 135 impl Sealed for str {} 136 impl Sealed for super::String {} 137 impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {} 138 } 139 140 /// Used in panic messages. 141 struct Type<'a>(&'a Value); 142 143 impl<'a> fmt::Display for Type<'a> { fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result144 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 145 match *self.0 { 146 Value::Null => formatter.write_str("null"), 147 Value::Bool(_) => formatter.write_str("boolean"), 148 Value::Number(_) => formatter.write_str("number"), 149 Value::String(_) => formatter.write_str("string"), 150 Value::Array(_) => formatter.write_str("array"), 151 Value::Object(_) => formatter.write_str("object"), 152 } 153 } 154 } 155 156 // The usual semantics of Index is to panic on invalid indexing. 157 // 158 // That said, the usual semantics are for things like Vec and BTreeMap which 159 // have different use cases than Value. If you are working with a Vec, you know 160 // that you are working with a Vec and you can get the len of the Vec and make 161 // sure your indices are within bounds. The Value use cases are more 162 // loosey-goosey. You got some JSON from an endpoint and you want to pull values 163 // out of it. Outside of this Index impl, you already have the option of using 164 // value.as_array() and working with the Vec directly, or matching on 165 // Value::Array and getting the Vec directly. The Index impl means you can skip 166 // that and index directly into the thing using a concise syntax. You don't have 167 // to check the type, you don't have to check the len, it is all about what you 168 // expect the Value to look like. 169 // 170 // Basically the use cases that would be well served by panicking here are 171 // better served by using one of the other approaches: get and get_mut, 172 // as_array, or match. The value of this impl is that it adds a way of working 173 // with Value that is not well served by the existing approaches: concise and 174 // careless and sometimes that is exactly what you want. 175 impl<I> ops::Index<I> for Value 176 where 177 I: Index, 178 { 179 type Output = Value; 180 181 /// Index into a `serde_json::Value` using the syntax `value[0]` or 182 /// `value["k"]`. 183 /// 184 /// Returns `Value::Null` if the type of `self` does not match the type of 185 /// the index, for example if the index is a string and `self` is an array 186 /// or a number. Also returns `Value::Null` if the given key does not exist 187 /// in the map or the given index is not within the bounds of the array. 188 /// 189 /// For retrieving deeply nested values, you should have a look at the 190 /// `Value::pointer` method. 191 /// 192 /// # Examples 193 /// 194 /// ``` 195 /// # use serde_json::json; 196 /// # 197 /// let data = json!({ 198 /// "x": { 199 /// "y": ["z", "zz"] 200 /// } 201 /// }); 202 /// 203 /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); 204 /// assert_eq!(data["x"]["y"][0], json!("z")); 205 /// 206 /// assert_eq!(data["a"], json!(null)); // returns null for undefined values 207 /// assert_eq!(data["a"]["b"], json!(null)); // does not panic 208 /// ``` index(&self, index: I) -> &Value209 fn index(&self, index: I) -> &Value { 210 static NULL: Value = Value::Null; 211 index.index_into(self).unwrap_or(&NULL) 212 } 213 } 214 215 impl<I> ops::IndexMut<I> for Value 216 where 217 I: Index, 218 { 219 /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or 220 /// `value["k"] = ...`. 221 /// 222 /// If the index is a number, the value must be an array of length bigger 223 /// than the index. Indexing into a value that is not an array or an array 224 /// that is too small will panic. 225 /// 226 /// If the index is a string, the value must be an object or null which is 227 /// treated like an empty object. If the key is not already present in the 228 /// object, it will be inserted with a value of null. Indexing into a value 229 /// that is neither an object nor null will panic. 230 /// 231 /// # Examples 232 /// 233 /// ``` 234 /// # use serde_json::json; 235 /// # 236 /// let mut data = json!({ "x": 0 }); 237 /// 238 /// // replace an existing key 239 /// data["x"] = json!(1); 240 /// 241 /// // insert a new key 242 /// data["y"] = json!([false, false, false]); 243 /// 244 /// // replace an array value 245 /// data["y"][0] = json!(true); 246 /// 247 /// // inserted a deeply nested key 248 /// data["a"]["b"]["c"]["d"] = json!(true); 249 /// 250 /// println!("{}", data); 251 /// ``` index_mut(&mut self, index: I) -> &mut Value252 fn index_mut(&mut self, index: I) -> &mut Value { 253 index.index_or_insert(self) 254 } 255 } 256