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::JsonValue;
15 use core::fmt::{Debug, Display, Formatter};
16 use std::collections::btree_map::{BTreeMap, Iter, IterMut};
17 
18 /// Object type, implemented using the standard library Btree.
19 ///
20 /// # Situation
21 /// * When the average number of objects exceeds 1024 (estimated value) but does not exceed 5000 (estimated value),
22 /// and the creation and query ratio is greater than 600.(Number of queries for 1 Object creation).
23 ///
24 /// * When the average number of objects exceeds 5000 (estimated value).
25 ///
26 /// # Attention
27 /// Only opening ` btree_object ` feature can be used, and associated with the object of other feature conflict. (Enabled by default)
28 ///
29 /// # Examples
30 /// ```
31 /// use ylong_json::Object;
32 ///
33 /// let object = Object::new();
34 /// assert_eq!(object.is_empty(), true);
35 /// ```
36 #[derive(Default, Clone, PartialEq)]
37 pub struct Object {
38     inner: BTreeMap<String, JsonValue>,
39 }
40 
41 impl Object {
42     /// Creates an empty Object.
43     ///
44     /// # Examples
45     /// ```
46     /// use ylong_json::Object;
47     ///
48     /// let object = Object::new();
49     /// assert_eq!(object.is_empty(), true);
50     /// ```
new() -> Self51     pub fn new() -> Self {
52         Self {
53             inner: BTreeMap::new(),
54         }
55     }
56 
57     /// Gets the length of Object.
58     ///
59     /// # Examples
60     /// ```
61     /// use ylong_json::{JsonValue, Object};
62     ///
63     /// let mut object = Object::new();
64     /// assert_eq!(object.len(), 0);
65     /// object.insert(String::from("null"), JsonValue::Null);
66     /// assert_eq!(object.len(), 1);
67     /// ```
len(&self) -> usize68     pub fn len(&self) -> usize {
69         self.inner.len()
70     }
71 
72     /// Determines whether the Object is empty.
73     ///
74     /// # Examples
75     /// ```
76     /// use ylong_json::{JsonValue, Object};
77     ///
78     /// let mut object = Object::new();
79     /// assert_eq!(object.is_empty(), true);
80     /// object.insert(String::from("null"), JsonValue::Null);
81     /// assert_eq!(object.is_empty(), false);
82     /// ```
is_empty(&self) -> bool83     pub fn is_empty(&self) -> bool {
84         self.inner.is_empty()
85     }
86 
87     /// Checks whether the specified key exists in the Object.
88     ///
89     /// # Examples
90     /// ```
91     /// use ylong_json::{JsonValue, Object, Number};
92     ///
93     /// let mut object = Object::new();
94     /// object.insert(String::from("null"), JsonValue::Null);
95     ///
96     /// assert_eq!(object.contains_key("null"), true);
97     /// assert_eq!(object.contains_key("no_such_key"), false);
98     /// ```
contains_key(&self, key: &str) -> bool99     pub fn contains_key(&self, key: &str) -> bool {
100         self.inner.contains_key(key)
101     }
102 
103     /// Inserts the specified key and value into the Object, and replaces the value if the key already exists in the Object.
104     ///
105     /// # Examples
106     /// ```
107     /// use ylong_json::{JsonValue, Object};
108     ///
109     /// let mut object = Object::new();
110     /// assert_eq!(object.len(), 0);
111     /// object.insert(String::from("null"), JsonValue::Null);
112     /// assert_eq!(object.len(), 1);
113     /// ```
insert(&mut self, key: String, value: JsonValue)114     pub fn insert(&mut self, key: String, value: JsonValue) {
115         self.inner.insert(key, value);
116     }
117 
118     /// Removes the element under the specified Key from Object.
119     ///
120     /// # Examples
121     /// ```
122     /// use ylong_json::{JsonValue, Object, Number};
123     ///
124     /// let mut object = Object::new();
125     /// object.insert(String::from("null"), JsonValue::Null);
126     /// assert_eq!(object.len(), 1);
127     /// assert_eq!(object.remove("null"), Some(JsonValue::Null));
128     /// assert_eq!(object.len(), 0);
129     /// ```
remove(&mut self, key: &str) -> Option<JsonValue>130     pub fn remove(&mut self, key: &str) -> Option<JsonValue> {
131         self.inner.remove(key)
132     }
133 
134     /// Gets a common iterator of Object.
135     ///
136     /// # Examples
137     /// ```
138     /// use ylong_json::Object;
139     ///
140     /// let object = Object::new();
141     /// let iter = object.iter();
142     /// ```
iter(&self) -> Iter<'_, String, JsonValue>143     pub fn iter(&self) -> Iter<'_, String, JsonValue> {
144         self.inner.iter()
145     }
146 
147     /// Gets a mutable iterator of Object.
148     ///
149     /// # Examples
150     /// ```
151     /// use ylong_json::Object;
152     ///
153     /// let mut object = Object::new();
154     /// let iter_mut = object.iter_mut();
155     /// ```
iter_mut(&mut self) -> IterMut<'_, String, JsonValue>156     pub fn iter_mut(&mut self) -> IterMut<'_, String, JsonValue> {
157         self.inner.iter_mut()
158     }
159 
160     /// Gets a common reference to the element in Object with the specified key.
161     ///
162     /// # Examples
163     /// ```
164     /// use ylong_json::{JsonValue, Object, Number};
165     ///
166     /// let mut object = Object::new();
167     /// object.insert(String::from("test"), JsonValue::Number(Number::from(123)));
168     ///
169     /// assert_eq!(object.get("test"), Some(&JsonValue::Number(Number::from(123))));
170     /// assert_eq!(object.get("no_such_key"), None);
171     /// ```
get(&self, key: &str) -> Option<&JsonValue>172     pub fn get(&self, key: &str) -> Option<&JsonValue> {
173         self.inner.get(key)
174     }
175 
176     /// Gets a mutable reference to the element in Object with the specified key.
177     ///
178     /// # Examples
179     /// ```
180     /// use ylong_json::{JsonValue, Object};
181     ///
182     /// let mut object = Object::new();
183     /// object.insert(String::from("null"), JsonValue::Null);
184     ///
185     /// assert_eq!(object.get_mut("null"), Some(&mut JsonValue::Null));
186     /// assert_eq!(object.get_mut("no_such_key"), None);
187     /// ```
get_mut(&mut self, key: &str) -> Option<&mut JsonValue>188     pub fn get_mut(&mut self, key: &str) -> Option<&mut JsonValue> {
189         self.inner.get_mut(key)
190     }
191 }
192 
193 impl Display for Object {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result194     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
195         write!(f, "{{")?;
196         for (n, (key, value)) in self.inner.iter().enumerate() {
197             if n != 0 {
198                 write!(f, ",")?;
199             }
200             write!(f, "\"{key}\":{value}")?;
201         }
202         write!(f, "}}")
203     }
204 }
205 
206 impl Debug for Object {
fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result207     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
208         Display::fmt(self, f)
209     }
210 }
211 
212 #[cfg(test)]
213 mod ut_btree {
214     use crate::{JsonValue, Object};
215 
216     /// UT test for `Object::iter_mut`.
217     ///
218     /// # Title
219     /// ut_object_iter_mut
220     ///
221     /// # Brief
222     /// 1. Creates some `Object`s.
223     /// 2. Calls `Object::iter_mut`.
224     /// 3. Checks if the test results are correct.
225     #[test]
ut_object_iter_mut()226     fn ut_object_iter_mut() {
227         let mut object = object!("key1" => "value1");
228         let mut iter = object.iter_mut();
229         assert_eq!(
230             iter.next(),
231             Some((&String::from("key1"), &mut JsonValue::new_string("value1")))
232         );
233         assert_eq!(iter.next(), None);
234     }
235 
236     /// UT test for `Object::fmt`.
237     ///
238     /// # Title
239     /// ut_object_fmt
240     ///
241     /// # Brief
242     /// 1. Creates a `Object`.
243     /// 2. Calls `Object::fmt` on it.
244     /// 3. Checks if the test results are correct.
245     #[test]
ut_object_fmt()246     fn ut_object_fmt() {
247         let object = object!("key1" => "value1"; "key2" => "value2");
248         assert_eq!(
249             format!("{object}"),
250             "{\"key1\":\"value1\",\"key2\":\"value2\"}"
251         );
252         assert_eq!(
253             format!("{object:?}"),
254             "{\"key1\":\"value1\",\"key2\":\"value2\"}"
255         );
256     }
257 
258     /// UT test for `Object::eq`.
259     ///
260     /// # Title
261     /// ut_object_fmt
262     ///
263     /// # Brief
264     /// 1. Creates a `Object`.
265     /// 2. Calls `Object::eq` on it.
266     /// 3. Checks if the test results are correct.
267     #[test]
ut_object_eq()268     fn ut_object_eq() {
269         let object1 = object!("key1" => "value1");
270         let object2 = object!("key1" => "value1"; "key2" => "value2");
271         let object3 = object!("key1" => "value1"; "key3" => "value3");
272 
273         assert_eq!(object1, object1);
274         assert_ne!(object1, object2);
275         assert_ne!(object2, object3);
276     }
277 }
278