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