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::{Cursor, CursorMut, Iter, IterMut, JsonValue, LinkedList, Node};
15 use core::fmt::{Debug, Display, Formatter};
16 use core::ptr::null;
17 
18 /// Object type, implemented using LinkedList.
19 ///
20 /// # Situation
21 /// * When the average number of items under Object is less than 15 (estimated value).
22 ///
23 /// * When the average number of items under Object exceeds 15 (estimated), but do not or rarely made the query operation.
24 ///
25 /// # Attention
26 /// * Only opening the 'list_object' feature, this Object type can be used , and it conflicts with other objects.
27 ///
28 /// * This Object ** does not provide the ** de-duplicate function.
29 /// * Users are required to ensure that there are no duplicate entries.
30 ///
31 /// * The output order of this Object is the same as the insertion order.
32 ///
33 /// # Examples
34 /// ```
35 /// use ylong_json::Object;
36 ///
37 /// let object = Object::new();
38 /// ```
39 #[derive(Default, Clone, PartialEq)]
40 pub struct Object {
41     inner: LinkedList<(String, JsonValue)>,
42 }
43 
44 impl Object {
45     /// Creates an empty Object。
46     ///
47     /// # Examples
48     /// ```
49     /// use ylong_json::Object;
50     ///
51     /// let object = Object::new();
52     /// assert_eq!(object.is_empty(), true);
53     /// ```
new() -> Self54     pub fn new() -> Self {
55         Self {
56             inner: LinkedList::new(),
57         }
58     }
59 
60     /// Gets the length of Object.
61     ///
62     /// # Examples
63     /// ```
64     /// use ylong_json::{JsonValue, Object};
65     ///
66     /// let mut object = Object::new();
67     /// assert_eq!(object.len(), 0);
68     /// object.insert(String::from("null"), JsonValue::Null);
69     /// assert_eq!(object.len(), 1);
70     /// ```
len(&self) -> usize71     pub fn len(&self) -> usize {
72         self.inner.len()
73     }
74 
75     /// Determines whether the Object is empty.
76     ///
77     /// # Examples
78     /// ```
79     /// use ylong_json::{JsonValue, Object};
80     ///
81     /// let mut object = Object::new();
82     /// assert_eq!(object.is_empty(), true);
83     /// object.insert(String::from("null"), JsonValue::Null);
84     /// assert_eq!(object.is_empty(), false);
85     /// ```
is_empty(&self) -> bool86     pub fn is_empty(&self) -> bool {
87         self.inner.is_empty()
88     }
89 
90     /// Checks whether the specified key exists in the Object.
91     ///
92     /// # Examples
93     /// ```
94     /// use ylong_json::{JsonValue, Object, Number};
95     ///
96     /// let mut object = Object::new();
97     /// object.insert(String::from("null"), JsonValue::Null);
98     ///
99     /// assert_eq!(object.contains_key("null"), true);
100     /// assert_eq!(object.contains_key("no_such_key"), false);
101     /// ```
contains_key(&self, key: &str) -> bool102     pub fn contains_key(&self, key: &str) -> bool {
103         self.get_cursor(key).is_some()
104     }
105 
106     /// Inserts the specified key and value into an Object, appending them to the end without deduplication.
107     ///
108     /// # Examples
109     /// ```
110     /// use ylong_json::{JsonValue, Object};
111     ///
112     /// let mut object = Object::new();
113     /// assert_eq!(object.len(), 0);
114     /// object.insert(String::from("null"), JsonValue::Null);
115     /// assert_eq!(object.len(), 1);
116     /// ```
insert(&mut self, key: String, value: JsonValue)117     pub fn insert(&mut self, key: String, value: JsonValue) {
118         self.inner.push_back((key, value))
119     }
120 
121     /// Removes the element under the specified key from the Object.If there is an element with
122     /// the same name in the Object, deletes the one with the smallest subscript.
123     ///
124     /// # Examples
125     /// ```
126     /// use ylong_json::{JsonValue, Object, Number};
127     ///
128     /// let mut object = Object::new();
129     /// object.insert(String::from("null"), JsonValue::Null);
130     /// assert_eq!(object.len(), 1);
131     /// assert_eq!(object.remove("null"), Some(JsonValue::Null));
132     /// assert_eq!(object.len(), 0);
133     /// ```
remove(&mut self, key: &str) -> Option<JsonValue>134     pub fn remove(&mut self, key: &str) -> Option<JsonValue> {
135         self.get_cursor_mut(key)?.remove_current().map(|(_, v)| v)
136     }
137 
138     /// Gets a common iterator of Object.
139     ///
140     /// # Examples
141     /// ```
142     /// use ylong_json::Object;
143     ///
144     /// let object = Object::new();
145     /// let iter = object.iter();
146     /// ```
iter(&self) -> Iter<'_, (String, JsonValue)>147     pub fn iter(&self) -> Iter<'_, (String, JsonValue)> {
148         self.inner.iter()
149     }
150 
151     /// Gets a mutable iterator of Object.
152     ///
153     /// # Examples
154     /// ```
155     /// use ylong_json::Object;
156     ///
157     /// let mut object = Object::new();
158     /// let iter_mut = object.iter_mut();
159     /// ```
iter_mut(&mut self) -> IterMut<'_, (String, JsonValue)>160     pub fn iter_mut(&mut self) -> IterMut<'_, (String, JsonValue)> {
161         self.inner.iter_mut()
162     }
163 
164     /// Gets a common reference to the element in Object with the specified key.
165     /// If there is an element with the same name, returns the one with the smallest subscript.
166     ///
167     /// # Examples
168     /// ```
169     /// use ylong_json::{JsonValue, Object, Number};
170     ///
171     /// let mut object = Object::new();
172     /// object.insert(String::from("test"), JsonValue::Number(Number::from(123)));
173     ///
174     /// assert_eq!(object.get("test"), Some(&JsonValue::Number(Number::from(123))));
175     /// assert_eq!(object.get("no_such_key"), None);
176     /// ```
get(&self, key: &str) -> Option<&JsonValue>177     pub fn get(&self, key: &str) -> Option<&JsonValue> {
178         self.get_cursor(key)?.current().map(|(_, v)| v)
179     }
180 
181     /// Gets a mutable reference to the element in Object with the specified key.
182     /// If there is an element with the same name, returns the one with the smallest subscript.
183     ///
184     /// # Examples
185     /// ```
186     /// use ylong_json::{JsonValue, Object};
187     ///
188     /// let mut object = Object::new();
189     /// object.insert(String::from("null"), JsonValue::Null);
190     ///
191     /// assert_eq!(object.get_mut("null"), Some(&mut JsonValue::Null));
192     /// assert_eq!(object.get_mut("no_such_key"), None);
193     /// ```
get_mut(&mut self, key: &str) -> Option<&mut JsonValue>194     pub fn get_mut(&mut self, key: &str) -> Option<&mut JsonValue> {
195         // Using get_cursor_mut causes a problem referencing temporary variables.
196         self.get_node_mut(key).map(|n| &mut n.get_element_mut().1)
197     }
198 
199     /// Gets a common reference to the node in Object with the specified key.
200     /// If there is an element with the same name, returns the one with the smallest subscript.
201     ///
202     /// After getting a common reference to a node, the node cannot be released. Otherwise, undefined behavior occurs.
203     ///
204     /// # Examples
205     /// ```
206     /// use ylong_json::{JsonValue, Object};
207     ///
208     /// let mut object = Object::new();
209     /// assert_eq!(object.get_node("no_such_key").is_none(), true);
210     ///
211     /// object.insert(String::from("null"), JsonValue::Null);
212     /// assert_eq!(object.get_node("null").is_some(), true);
213     /// ```
get_node(&self, key: &str) -> Option<&Node<(String, JsonValue)>>214     pub fn get_node(&self, key: &str) -> Option<&Node<(String, JsonValue)>> {
215         self.get_cursor(key)?.current_node()
216     }
217 
218     /// Gets a mutable reference to the node in Object with the specified key.
219     /// If there is an element with the same name, returns the one with the smallest subscript.
220     ///
221     /// After getting a mutable reference to a node, the node cannot be released. Otherwise, undefined behavior occurs.
222     ///
223     /// # Examples
224     /// ```
225     /// use ylong_json::{JsonValue, Object};
226     ///
227     /// let mut object = Object::new();
228     /// assert_eq!(object.get_node_mut("no_such_key").is_none(), true);
229     ///
230     /// object.insert(String::from("null"), JsonValue::Null);
231     /// assert_eq!(object.get_node_mut("null").is_some(), true);
232     /// ```
get_node_mut(&mut self, key: &str) -> Option<&mut Node<(String, JsonValue)>>233     pub fn get_node_mut(&mut self, key: &str) -> Option<&mut Node<(String, JsonValue)>> {
234         self.get_cursor_mut(key)?.current_node()
235     }
236 
237     /// Gets the last node.
238     #[cfg(feature = "c_adapter")]
last_node_mut(&mut self) -> Option<&mut Node<(String, JsonValue)>>239     pub(crate) fn last_node_mut(&mut self) -> Option<&mut Node<(String, JsonValue)>> {
240         let mut cursor = self.inner.cursor_back_mut();
241         let _ = cursor.index()?;
242         cursor.current_node()
243     }
244 
245     /// Needs using this method to avoid the life cycle check, which involves unsafe operations.
get_key_mut_maybe_insert(&mut self, key: &str) -> &mut JsonValue246     pub(crate) fn get_key_mut_maybe_insert(&mut self, key: &str) -> &mut JsonValue {
247         let mut cursor = self.inner.cursor_front();
248         let mut ptr = null();
249         while cursor.index().is_some() {
250             let current = cursor.current().unwrap();
251             if current.0 == key {
252                 ptr = cursor.current_node_ptr();
253                 break;
254             }
255             cursor.move_next();
256         }
257 
258         if ptr.is_null() {
259             self.insert(String::from(key), JsonValue::Null);
260             &mut self.inner.back_mut().unwrap().1
261         } else {
262             unsafe {
263                 &mut (*(ptr as *mut Node<(String, JsonValue)>))
264                     .get_element_mut()
265                     .1
266             }
267         }
268     }
269 
270     /// Gets the common cursor of the node corresponding to the specified key.
get_cursor(&self, key: &str) -> Option<Cursor<'_, (String, JsonValue)>>271     fn get_cursor(&self, key: &str) -> Option<Cursor<'_, (String, JsonValue)>> {
272         let mut cursor = self.inner.cursor_front();
273         while cursor.index().is_some() {
274             let (k, _) = cursor.current().unwrap();
275             if key == k {
276                 return Some(cursor);
277             }
278             cursor.move_next();
279         }
280         None
281     }
282 
283     /// Gets the mutable cursor of the node corresponding to the specified key.
get_cursor_mut(&mut self, key: &str) -> Option<CursorMut<'_, (String, JsonValue)>>284     fn get_cursor_mut(&mut self, key: &str) -> Option<CursorMut<'_, (String, JsonValue)>> {
285         let mut cursor = self.inner.cursor_front_mut();
286         while cursor.index().is_some() {
287             let (k, _) = cursor.current().unwrap();
288             if key == k {
289                 return Some(cursor);
290             }
291             cursor.move_next();
292         }
293         None
294     }
295 }
296 
297 impl Display for Object {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result298     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
299         write!(f, "{{")?;
300         for (n, (key, value)) in self.inner.iter().enumerate() {
301             if n != 0 {
302                 write!(f, ",")?;
303             }
304             write!(f, "\"{key}\":{value}")?;
305         }
306         write!(f, "}}")
307     }
308 }
309 
310 impl Debug for Object {
fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result311     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
312         Display::fmt(self, f)
313     }
314 }
315 
316 #[cfg(test)]
317 mod ut_linked_list {
318     use crate::{JsonValue, Object};
319 
320     /// UT test for `Object::contains_key`.
321     ///
322     /// # Title
323     /// ut_object_contains_key
324     ///
325     /// # Brief
326     /// 1. Creates a `Object`.
327     /// 2. Calls `Object::contains_key` on it.
328     /// 3. Checks  if the test results are correct.
329     #[test]
ut_object_contains_key()330     fn ut_object_contains_key() {
331         let object = object!("key1" => "value1");
332         assert!(object.contains_key("key1"));
333         assert!(!object.contains_key("key2"));
334     }
335 
336     /// UT test for `Object::iter_mut`.
337     ///
338     /// # Title
339     /// ut_object_iter_mut
340     ///
341     /// # Brief
342     /// 1. Creates a `Object`.
343     /// 2. Calls `Object::iter_mut` on it.
344     /// 3. Checks  if the test results are correct.
345     #[test]
ut_object_iter_mut()346     fn ut_object_iter_mut() {
347         let mut object = object!("key1" => "value1");
348         let mut iter_mut = object.iter_mut();
349         assert_eq!(
350             iter_mut.next(),
351             Some(&mut (String::from("key1"), JsonValue::new_string("value1")))
352         );
353         assert_eq!(iter_mut.next(), None);
354     }
355 
356     /// UT test for `Object::get_mut`.
357     ///
358     /// # Title
359     /// ut_object_get_mut
360     ///
361     /// # Brief
362     /// 1. Creates a `Object`.
363     /// 2. Calls `Object::get_mut` on it.
364     /// 3. Checks  if the test results are correct.
365     #[test]
ut_object_get_mut()366     fn ut_object_get_mut() {
367         let mut object = object!("key1" => "value1");
368         assert_eq!(
369             object.get_mut("key1"),
370             Some(&mut JsonValue::new_string("value1"))
371         );
372         assert_eq!(object.get_mut("key2"), None);
373     }
374 
375     /// UT test for `Object::get_node`.
376     ///
377     /// # Title
378     /// ut_object_get_node
379     ///
380     /// # Brief
381     /// 1. Creates a `Object`.
382     /// 2. Calls `Object::get_node` on it.
383     /// 3. Checks  if the test results are correct.
384     #[test]
ut_object_get_node()385     fn ut_object_get_node() {
386         let object = object!("key1" => "value1");
387         assert!(object.get_node("key1").is_some());
388         assert!(object.get_node("key2").is_none());
389     }
390 
391     /// UT test for `Object::get_node_mut`.
392     ///
393     /// # Title
394     /// ut_object_get_node_mut
395     ///
396     /// # Brief
397     /// 1. Creates a `Object`.
398     /// 2. Calls `Object::get_node_mut` on it.
399     /// 3. Checks  if the test results are correct.
400     #[test]
ut_object_get_node_mut()401     fn ut_object_get_node_mut() {
402         let mut object = object!("key1" => "value1");
403         assert!(object.get_node_mut("key1").is_some());
404         assert!(object.get_node_mut("key2").is_none());
405     }
406 
407     /// UT test for `Object::fmt`.
408     ///
409     /// # Title
410     /// ut_object_fmt
411     ///
412     /// # Brief
413     /// 1. Creates a `Object`.
414     /// 2. Calls `Object::fmt` on it.
415     /// 3. Checks  if the test results are correct.
416     #[test]
ut_object_fmt()417     fn ut_object_fmt() {
418         let object = object!("key1" => "value1"; "key2" => "value2");
419         assert_eq!(
420             format!("{object}"),
421             "{\"key1\":\"value1\",\"key2\":\"value2\"}"
422         );
423         assert_eq!(
424             format!("{object:?}"),
425             "{\"key1\":\"value1\",\"key2\":\"value2\"}"
426         );
427     }
428 }
429