1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use crate::{Array, JsonValue, Object}; 15 16 /// Static NULL, which is returned if the searched key-value pair does not exist. 17 static NULL: JsonValue = JsonValue::Null; 18 19 /// This trait can be used to get an index based on the subscript of an internal member of JsonValue. 20 pub trait Index: private::IndexSealed { 21 /// Gets a common reference to the value with the specified subscript (or key) from a JsonValue. index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue22 fn index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue; 23 24 /// Gets a mutable reference to the value of the specified subscript (or key) from a JsonValue. index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue25 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue; 26 27 /// Removes the member with the specified subscript (or key) from a JsonValue. index_remove(&self, value: &mut JsonValue) -> Option<JsonValue>28 fn index_remove(&self, value: &mut JsonValue) -> Option<JsonValue>; 29 } 30 31 impl Index for usize { 32 /// Uses the array subscript to visit the Array type of JsonValue 33 /// and get a common reference to the corresponding JsonValue. 34 /// A null type will be returned in the following two cases: 35 /// 36 /// 1.Use a subscript to visit non-array types. 37 /// 38 /// 2.The subscript exceeds the current length of the Array type. 39 /// 40 /// # Examples 41 /// ``` 42 /// use ylong_json::{JsonValue, Array}; 43 /// 44 /// // Non-array types 45 /// assert_eq!(JsonValue::Number(0.0.into())[0], JsonValue::Null); 46 /// 47 /// // Array type 48 /// let mut array = Array::new(); 49 /// array.push(JsonValue::Null); 50 /// array.push(JsonValue::Boolean(true)); 51 /// array.push(JsonValue::Number(0.0.into())); 52 /// 53 /// let value = JsonValue::Array(array); 54 /// 55 /// // When subscript < length 56 /// assert_eq!(value[0], JsonValue::Null); 57 /// assert_eq!(value[1], JsonValue::Boolean(true)); 58 /// assert_eq!(value[2], JsonValue::Number(0.0.into())); 59 /// // When subscript >= length 60 /// assert_eq!(value[3], JsonValue::Null); 61 /// ``` index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue62 fn index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue { 63 if let JsonValue::Array(ref array) = value { 64 if *self < array.len() { 65 return array.get(*self).unwrap(); 66 } 67 } 68 &NULL 69 } 70 71 /// Uses the array subscript to visit the Array type of JsonValue 72 /// and get a mutable reference to the corresponding JsonValue. 73 /// 74 /// If the visited JsonValue is not Array type, the JsonValue will be 75 /// replaced with an empty Array type and visits again with that subscript. 76 /// 77 /// If the visited JsonValue is Array type, but the subscript exceeds the length of the array, 78 /// then adds a Null type JsonValue at the end of the array and return a mutable reference of it. 79 /// 80 /// # Examples 81 /// ``` 82 /// use ylong_json::{JsonValue, Array}; 83 /// 84 /// // Non-array types 85 /// let mut value = JsonValue::Null; 86 /// value[0] = JsonValue::Null; 87 /// 88 /// let mut array = Array::new(); 89 /// array.push(JsonValue::Null); 90 /// assert_eq!(value, JsonValue::Array(array)); 91 /// 92 /// // Array type 93 /// let mut array = Array::new(); 94 /// array.push(JsonValue::Null); 95 /// let mut value = JsonValue::Array(array); 96 /// 97 /// // Contains the subscript 98 /// value[0] = JsonValue::Number(0.0.into()); 99 /// assert_eq!(value[0], JsonValue::Number(0.0.into())); 100 /// assert_eq!(value.try_as_array().unwrap().len(), 1); 101 /// 102 /// // Does not contain the subscript 103 /// value[1] = JsonValue::Boolean(true); 104 /// assert_eq!(value[1], JsonValue::Boolean(true)); 105 /// assert_eq!(value.try_as_array().unwrap().len(), 2); 106 /// ``` index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue107 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue { 108 if let JsonValue::Array(ref mut array) = value { 109 return if *self < array.len() { 110 array.get_mut(*self).unwrap() 111 } else { 112 array.push(JsonValue::Null); 113 array.last_mut().unwrap() 114 }; 115 } 116 *value = JsonValue::new_array(Array::new()); 117 self.index_into_mut(value) 118 } 119 120 /// Removes the element at the specified location of Array type JsonValue and returns that content. 121 /// 122 /// # Examples 123 /// ``` 124 /// use ylong_json::{JsonValue, Array}; 125 /// 126 /// let mut array = Array::new(); 127 /// array.push(1i32.into()); 128 /// 129 /// let mut value: JsonValue = JsonValue::Array(array); 130 /// assert_eq!(value[0], 1i32.into()); 131 /// 132 /// let ret = value.remove(0); 133 /// assert_eq!(value[0], JsonValue::Null); 134 /// assert_eq!(ret.unwrap(), 1i32.into()); 135 /// ``` index_remove(&self, value: &mut JsonValue) -> Option<JsonValue>136 fn index_remove(&self, value: &mut JsonValue) -> Option<JsonValue> { 137 if let JsonValue::Array(ref mut array) = value { 138 if *self < array.len() { 139 return array.remove(*self); 140 } 141 } 142 None 143 } 144 } 145 146 impl Index for str { 147 /// Uses key to visit Object type JsonValue, and returns a common reference to corresponding JsonValue. 148 /// A null type will be returned in the following two cases: 149 /// 150 /// 1.Uses key to visit non-object types. 151 /// 152 /// 2.The searched Object type does not contain the key. 153 /// 154 /// # Examples 155 /// ``` 156 /// use ylong_json::{JsonValue, Object}; 157 /// 158 /// // Non-object types 159 /// assert_eq!(JsonValue::Number(0.0.into())["key"], JsonValue::Null); 160 /// 161 /// // Object type 162 /// let mut object = Object::new(); 163 /// object.insert(String::from("key"), JsonValue::Number(0.0.into())); 164 /// 165 /// let value = JsonValue::Object(object); 166 /// 167 /// // The key exists. 168 /// assert_eq!(value["key"], JsonValue::Number(0.0.into())); 169 /// 170 /// // The key does not exist. 171 /// assert_eq!(value["not exist"], JsonValue::Null); 172 /// ``` index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue173 fn index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue { 174 if let JsonValue::Object(ref object) = value { 175 return object.get(self).unwrap_or(&NULL); 176 } 177 &NULL 178 } 179 180 /// Uses key to visit Object type JsonValue, and returns a mutable reference to corresponding JsonValue. 181 /// 182 /// If the visited JsonValue is not Object type, the JsonValue will be 183 /// replaced with an empty Object type and visits again with that key. 184 /// 185 /// If the visited JsonValue is of object type but does not contain the key, a key-value pair of 186 /// the key and a null type will be inserted and returns a mutable reference to the JsonValue. 187 /// 188 /// 189 /// # Examples 190 /// ``` 191 /// use ylong_json::{JsonValue, Object}; 192 /// 193 /// // Non-object types 194 /// let mut value = JsonValue::Null; 195 /// let mut object = Object::new(); 196 /// object.insert(String::from("key"), JsonValue::Number(0.0.into())); 197 /// 198 /// value["key"] = JsonValue::Number(0.0.into()); 199 /// assert_eq!(value, JsonValue::Object(object)); 200 /// 201 /// // Object type 202 /// let mut object = Object::new(); 203 /// object.insert(String::from("key"), JsonValue::Number(0.0.into())); 204 /// let mut value = JsonValue::Object(object); 205 /// 206 /// // Contains the key. 207 /// value["key"] = JsonValue::Boolean(true); 208 /// assert_eq!(value["key"], JsonValue::Boolean(true)); 209 /// assert_eq!(value.try_as_mut_object().unwrap().len(), 1); 210 /// 211 /// // Dose not contain the key. 212 /// value["not exist"] = JsonValue::Number(1.1.into()); 213 /// assert_eq!(value["not exist"], JsonValue::Number(1.1.into())); 214 /// assert_eq!(value.try_as_mut_object().unwrap().len(), 2); 215 /// ``` index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue216 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue { 217 if let JsonValue::Object(ref mut object) = value { 218 #[cfg(feature = "list_object")] 219 { 220 return object.get_key_mut_maybe_insert(self); 221 } 222 #[cfg(feature = "vec_object")] 223 { 224 if let Some(pos) = object.iter().position(|(k, _)| k == self) { 225 return object.get_mut_by_position(pos).unwrap(); 226 } 227 object.insert(String::from(self), JsonValue::Null); 228 return object.last_mut().unwrap(); 229 } 230 #[cfg(feature = "btree_object")] 231 { 232 if !object.contains_key(self) { 233 object.insert(String::from(self), JsonValue::Null); 234 } 235 return object.get_mut(self).unwrap(); 236 } 237 } 238 *value = JsonValue::Object(Object::new()); 239 self.index_into_mut(value) 240 } 241 242 /// Removes the element at the specified location of Object type JsonValue and returns that content. 243 /// 244 /// # Examples 245 /// ``` 246 /// use ylong_json::{Object, JsonValue}; 247 /// 248 /// let mut object = Object::new(); 249 /// object.insert(String::from("key"), "value".into()); 250 /// 251 /// let mut value: JsonValue = object.into(); 252 /// assert_eq!(value["key"], "value".into()); 253 /// 254 /// let ret = value.remove("key"); 255 /// assert_eq!(value["key"], JsonValue::Null); 256 /// assert_eq!(ret.unwrap(), "value".into()); 257 /// ``` index_remove(&self, value: &mut JsonValue) -> Option<JsonValue>258 fn index_remove(&self, value: &mut JsonValue) -> Option<JsonValue> { 259 if let JsonValue::Object(ref mut object) = value { 260 return object.remove(self); 261 } 262 None 263 } 264 } 265 266 impl Index for String { 267 /// Same as 'Index for str'. index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue268 fn index_into<'a>(&self, value: &'a JsonValue) -> &'a JsonValue { 269 self.as_str().index_into(value) 270 } 271 272 /// Same as 'Index for str'. index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue273 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> &'a mut JsonValue { 274 self.as_str().index_into_mut(value) 275 } 276 277 /// Same as 'Index for str'. index_remove(&self, value: &mut JsonValue) -> Option<JsonValue>278 fn index_remove(&self, value: &mut JsonValue) -> Option<JsonValue> { 279 self.as_str().index_remove(value) 280 } 281 } 282 283 impl<'a, T> Index for &'a T 284 where 285 T: ?Sized + Index, 286 { 287 /// Implements Index for the relevant reference type. index_into<'v>(&self, value: &'v JsonValue) -> &'v JsonValue288 fn index_into<'v>(&self, value: &'v JsonValue) -> &'v JsonValue { 289 (**self).index_into(value) 290 } 291 292 /// Implements Index for the relevant reference type. index_into_mut<'v>(&self, value: &'v mut JsonValue) -> &'v mut JsonValue293 fn index_into_mut<'v>(&self, value: &'v mut JsonValue) -> &'v mut JsonValue { 294 (**self).index_into_mut(value) 295 } 296 297 /// Implements Index for the relevant reference type. index_remove(&self, value: &mut JsonValue) -> Option<JsonValue>298 fn index_remove(&self, value: &mut JsonValue) -> Option<JsonValue> { 299 (**self).index_remove(value) 300 } 301 } 302 303 // To prevent the Index by external implementation. 304 mod private { 305 pub trait IndexSealed {} 306 307 impl IndexSealed for usize {} 308 309 impl IndexSealed for str {} 310 311 impl IndexSealed for String {} 312 313 impl<'a, T> IndexSealed for &'a T where T: ?Sized + IndexSealed {} 314 } 315 316 #[cfg(test)] 317 mod ut_index { 318 use crate::{Array, Index, JsonValue, Object}; 319 320 /// UT test for `usize::index_into`. 321 /// 322 /// # Title 323 /// ut_usize_index_into 324 /// 325 /// # Brief 326 /// 1. Creates some `usize`s and some `JsonValue`s. 327 /// 2. Calls `Index::index_into`. 328 /// 3. Checks if the test results are correct. 329 #[test] ut_usize_index_into()330 fn ut_usize_index_into() { 331 let value = JsonValue::new_boolean(true); 332 assert!(1usize.index_into(&value).is_null()); 333 } 334 335 /// UT test for `usize::index_into_mut`. 336 /// 337 /// # Title 338 /// ut_usize_index_into_mut 339 /// 340 /// # Brief 341 /// 1. Creates some `usize`s and some `JsonValue`s. 342 /// 2. Calls `Index::index_into_mut`. 343 /// 3. Checks if the test results are correct. 344 #[test] ut_usize_index_into_mut()345 fn ut_usize_index_into_mut() { 346 let mut value = JsonValue::new_array(array!(1)); 347 assert!(0usize.index_into_mut(&mut value).is_number()); 348 assert!(1usize.index_into_mut(&mut value).is_null()); 349 350 let mut value = JsonValue::new_null(); 351 assert!(0usize.index_into_mut(&mut value).is_null()); 352 assert!(value.is_array()) 353 } 354 355 /// UT test for `usize::index_remove`. 356 /// 357 /// # Title 358 /// ut_usize_index_remove 359 /// 360 /// # Brief 361 /// 1. Creates some `usize`s and some `JsonValue`s. 362 /// 2. Calls `Index::index_remove`. 363 /// 3. Checks if the test results are correct. 364 #[test] ut_usize_index_remove()365 fn ut_usize_index_remove() { 366 let mut value = JsonValue::new_array(array!(1)); 367 assert_eq!( 368 0usize.index_remove(&mut value), 369 Some(JsonValue::new_number(1.into())) 370 ); 371 assert!(0usize.index_remove(&mut value).is_none()); 372 } 373 374 /// UT test for `str::index_into`. 375 /// 376 /// # Title 377 /// ut_str_index_into 378 /// 379 /// # Brief 380 /// 1. Creates some `str`s and some `JsonValue`s. 381 /// 2. Calls `Index::index_into`. 382 /// 3. Checks if the test results are correct. 383 #[test] ut_str_index_into()384 fn ut_str_index_into() { 385 let value = JsonValue::new_boolean(true); 386 assert!("key".index_into(&value).is_null()); 387 } 388 389 /// UT test for `str::index_into_mut`. 390 /// 391 /// # Title 392 /// ut_str_index_into_mut 393 /// 394 /// # Brief 395 /// 1. Creates some `str`s and some `JsonValue`s. 396 /// 2. Calls `Index::index_into_mut`. 397 /// 3. Checks if the test results are correct. 398 #[test] ut_str_index_into_mut()399 fn ut_str_index_into_mut() { 400 let mut value = JsonValue::new_object(object!("key1" => "value1")); 401 assert!("key1".index_into_mut(&mut value).is_string()); 402 assert!("key2".index_into_mut(&mut value).is_null()); 403 404 let mut value = JsonValue::new_null(); 405 assert!("key1".index_into_mut(&mut value).is_null()); 406 assert!(value.is_object()) 407 } 408 409 /// UT test for `str::index_remove`. 410 /// 411 /// # Title 412 /// ut_str_index_remove 413 /// 414 /// # Brief 415 /// 1. Creates some `str`s and some `JsonValue`s. 416 /// 2. Calls `Index::index_remove`. 417 /// 3. Checks if the test results are correct. 418 #[test] ut_str_index_remove()419 fn ut_str_index_remove() { 420 let mut value = JsonValue::new_object(object!("key1" => "value1")); 421 assert_eq!( 422 "key1".index_remove(&mut value), 423 Some(JsonValue::new_string("value1")) 424 ); 425 426 let mut value = JsonValue::new_null(); 427 assert!("key1".index_remove(&mut value).is_none()); 428 } 429 430 /// UT test for `String::index_into`. 431 /// 432 /// # Title 433 /// ut_string_index_into 434 /// 435 /// # Brief 436 /// 1. Creates some `String`s and some `JsonValue`s. 437 /// 2. Calls `Index::index_into`. 438 /// 3. Checks if the test results are correct. 439 #[test] ut_string_index_into()440 fn ut_string_index_into() { 441 let value = JsonValue::new_boolean(true); 442 assert!(String::from("key").index_into(&value).is_null()); 443 } 444 445 /// UT test for `String::index_into_mut`. 446 /// 447 /// # Title 448 /// ut_string_index_into_mut 449 /// 450 /// # Brief 451 /// 1. Creates some `String`s and some `JsonValue`s. 452 /// 2. Calls `Index::index_into_mut`. 453 /// 3. Checks if the test results are correct. 454 #[test] ut_string_index_into_mut()455 fn ut_string_index_into_mut() { 456 let mut value = JsonValue::new_object(object!("key1" => "value1")); 457 assert!(String::from("key1").index_into_mut(&mut value).is_string()); 458 assert!(String::from("key2").index_into_mut(&mut value).is_null()); 459 460 let mut value = JsonValue::new_null(); 461 assert!(String::from("key1").index_into_mut(&mut value).is_null()); 462 assert!(value.is_object()) 463 } 464 465 /// UT test for `String::index_remove`. 466 /// 467 /// # Title 468 /// ut_string_index_remove 469 /// 470 /// # Brief 471 /// 1. Creates some `String`s and some `JsonValue`s. 472 /// 2. Calls `Index::index_remove`. 473 /// 3. Checks if the test results are correct. 474 #[test] ut_string_index_remove()475 fn ut_string_index_remove() { 476 let mut value = JsonValue::new_object(object!("key1" => "value1")); 477 assert_eq!( 478 String::from("key1").index_remove(&mut value), 479 Some(JsonValue::new_string("value1")) 480 ); 481 assert!(String::from("key1").index_remove(&mut value).is_none()); 482 } 483 } 484