json_node/models/
json_node.rs

1use std::fmt::Display;
2
3use crate::models::JsonPropertyMap;
4use crate::parsing::JsonNodeParser;
5use crate::utils::SurroundWith;
6use crate::Result;
7
8#[derive(Debug, PartialEq, Clone)]
9pub enum JsonNode {
10    Object(JsonPropertyMap),
11    Array(Vec<JsonNode>),
12    String(String),
13    Integer(i64),
14    Float(f64),
15    Boolean(bool),
16    Null,
17}
18
19impl JsonNode {
20    /// Parse a JSON string slice into a `JsonNode` structure.
21    /// 
22    /// # Arguments
23    /// 
24    /// * `json` - The JSON you wish to be parsed.
25    /// 
26    /// # Examples
27    /// 
28    /// ```
29    /// use json_node::JsonNode;
30    /// 
31    /// // Create a valid JSON string.
32    /// let json = "10";
33    /// // Manually create a tree with the expected structure and value.
34    /// let expected = JsonNode::Integer(10);
35    /// 
36    /// // Parse the json string into a node tree.
37    /// let node_tree = JsonNode::parse(json).unwrap();
38    /// 
39    /// assert_eq!(node_tree, expected);
40    /// ```
41    pub fn parse(json: &str) -> Result<JsonNode> {
42        JsonNodeParser::parse_node(json, None)
43    }
44
45    /// Checks if the node is the JsonNode::Object discriminant.
46    /// 
47    /// # Examples
48    /// 
49    /// ```
50    /// use json_node::{JsonNode, JsonPropertyMap};
51    /// 
52    /// // Create an object node.
53    /// let object_node = JsonNode::Object(JsonPropertyMap::new());
54    /// // Create a non-object node.
55    /// let non_object_node = JsonNode::Null;
56    /// 
57    /// assert!(object_node.is_object());
58    /// assert!(!non_object_node.is_object())
59    /// ```
60    pub fn is_object(&self) -> bool {
61        match self {
62            JsonNode::Object(_) => true,
63            _ => false,
64        }
65    }
66
67    /// Checks if the node is the JsonNode::Array discriminant.
68    /// 
69    /// # Examples
70    /// 
71    /// ```
72    /// use json_node::JsonNode;
73    /// // Create an array node.
74    /// let array_node = JsonNode::Array(Vec::new());
75    /// // Create a non-array node.
76    /// let non_array_node = JsonNode::Null;
77    /// 
78    /// assert!(array_node.is_array());
79    /// assert!(!non_array_node.is_array())
80    /// ```
81    pub fn is_array(&self) -> bool {
82        match self {
83            JsonNode::Array(_) => true,
84            _ => false,
85        }
86    }
87
88    /// Extracts the `JsonPropertyMap` contained inside the node if it is the `JsonNode::Object` discriminant.
89    /// 
90    /// # Examples
91    /// 
92    /// ```
93    /// use json_node::{JsonNode, JsonPropertyMap};
94    /// 
95    /// // Create an object node.
96    /// let object_node = JsonNode::Object(JsonPropertyMap::new());
97    /// 
98    /// // Extract `JsonPropertyMap`.
99    /// let as_object_some = object_node.as_object(); // Option<&JsonPropertyMap>
100    /// 
101    /// assert_eq!(as_object_some, Some(&JsonPropertyMap::new()));
102    /// 
103    /// // Create a non-object node.
104    /// let non_object_node = JsonNode::Null;
105    /// 
106    /// // Fail to extract `JsonPropertyMap`.
107    /// let as_object_none = non_object_node.as_object();
108    /// 
109    /// assert_eq!(as_object_none, None);
110    /// ```
111    pub fn as_object(&self) -> Option<&JsonPropertyMap> {
112        match self {
113            JsonNode::Object(object) => Some(object),
114            _ => None,
115        }
116    }
117
118    /// Extracts the `Vec<JsonNode>` contained inside the node if it is the `JsonNode::Array` discriminant.
119    /// 
120    /// # Examples
121    /// 
122    /// ```
123    /// use json_node::JsonNode;
124    /// 
125    /// // Create an array node.
126    /// let array_node = JsonNode::Array(Vec::new());
127    /// 
128    /// // Extract `Vec<JsonNode>`.
129    /// let as_array_some = array_node.as_array(); // Option<&Vec<JsonNode>>
130    /// 
131    /// assert_eq!(as_array_some, Some(&Vec::new()));
132    /// 
133    /// // Create a non-array node.
134    /// let non_array_node = JsonNode::Null;
135    /// 
136    /// // Fail to extract `Vec<JsonNode>`.
137    /// let as_array_none = non_array_node.as_array();
138    /// 
139    /// assert_eq!(as_array_none, None);
140    /// ```
141    pub fn as_array(&self) -> Option<&Vec<JsonNode>> {
142        match self {
143            JsonNode::Array(array) => Some(array),
144            _ => None,
145        }
146    }
147
148    /// Extracts the `JsonPropertyMap` contained inside the node if it is the `JsonNode::Object` discriminant as a mutable value.
149    /// 
150    /// # Examples
151    /// 
152    /// ```
153    /// use json_node::{JsonNode, JsonPropertyMap};
154    /// 
155    /// // Create an object node.
156    /// let mut object_node = JsonNode::Object(JsonPropertyMap::new());
157    /// 
158    /// // Extract `JsonPropertyMap`.
159    /// let as_object_some = object_node.as_object_mut(); // Option<&mut JsonPropertyMap>
160    /// 
161    /// assert_eq!(as_object_some, Some(&mut JsonPropertyMap::new()));
162    /// 
163    /// // Create a non-object node.
164    /// let mut non_object_node = JsonNode::Null;
165    /// 
166    /// // Fail to extract `JsonPropertyMap`.
167    /// let as_object_none = non_object_node.as_object_mut();
168    /// 
169    /// assert_eq!(as_object_none, None);
170    /// ```
171    pub fn as_object_mut(&mut self) -> Option<&mut JsonPropertyMap> {
172        match self {
173            JsonNode::Object(object) => Some(object),
174            _ => None,
175        }
176    }
177
178    /// Extracts the `Vec<JsonNode>` contained inside the node if it is the `JsonNode::Array` discriminant as a mutable value.
179    /// 
180    /// # Examples
181    /// 
182    /// ```
183    /// use json_node::{JsonNode, JsonPropertyMap};
184    /// 
185    /// // Create an array node.
186    /// let mut array_node = JsonNode::Array(Vec::new());
187    /// 
188    /// // Extract `Vec<JsonNode>`.
189    /// let as_array_some = array_node.as_array_mut(); // Option<&mut Vec<JsonNode>>
190    /// 
191    /// assert_eq!(as_array_some, Some(&mut Vec::new()));
192    /// 
193    /// // Create a non-array node.
194    /// let mut non_array_node = JsonNode::Null;
195    /// 
196    /// // Fail to extract `JsonPropertyMap`.
197    /// let as_array_none = non_array_node.as_array_mut();
198    /// 
199    /// assert_eq!(as_array_none, None);
200    /// ```
201    pub fn as_array_mut(&mut self) -> Option<&mut Vec<JsonNode>> {
202        match self {
203            JsonNode::Array(array) => Some(array),
204            _ => None,
205        }
206    }
207
208    /// Checks if the value is the `JsonNode::String` discriminant.
209    /// 
210    /// # Examples
211    /// 
212    /// ```
213    /// use json_node::JsonNode;
214    /// 
215    /// let string_value = JsonNode::String("Hello World!".to_owned());
216    /// let non_string_value = JsonNode::Null;
217    /// 
218    /// assert!(string_value.is_string());
219    /// assert!(!non_string_value.is_string());
220    /// ```
221    pub fn is_string(&self) -> bool {
222        match self {
223            JsonNode::String(_) => true,
224            _ => false,
225        }
226    }
227
228    /// Checks if the value is the `JsonNode::Integer` discriminant.
229    /// 
230    /// # Examples
231    /// 
232    /// ```
233    /// use json_node::JsonNode;
234    /// 
235    /// let integer_value = JsonNode::Integer(42);
236    /// let non_integer_value = JsonNode::Null;
237    /// 
238    /// assert!(integer_value.is_integer());
239    /// assert!(!non_integer_value.is_integer());
240    /// ```
241    pub fn is_integer(&self) -> bool {
242        match self {
243            JsonNode::Integer(_) => true,
244            _ => false,
245        }
246    }
247
248    /// Checks if the value is the `JsonNode::Float` discriminant.
249    /// 
250    /// # Examples
251    /// 
252    /// ```
253    /// use json_node::JsonNode;
254    /// 
255    /// let float_value = JsonNode::Float(3.14);
256    /// let non_float_value = JsonNode::Null;
257    /// 
258    /// assert!(float_value.is_float());
259    /// assert!(!non_float_value.is_float());
260    /// ```
261    pub fn is_float(&self) -> bool {
262        match self {
263            JsonNode::Float(_) => true,
264            _ => false,
265        }
266    }
267
268    /// Checks if the value is the `JsonNode::Boolean` discriminant.
269    /// 
270    /// # Examples
271    /// 
272    /// ```
273    /// use json_node::JsonNode;
274    /// 
275    /// let bool_value = JsonNode::Boolean(true);
276    /// let non_bool_value = JsonNode::Null;
277    /// 
278    /// assert!(bool_value.is_bool());
279    /// assert!(!non_bool_value.is_bool());
280    /// ```
281    pub fn is_bool(&self) -> bool {
282        match self {
283            JsonNode::Boolean(_) => true,
284            _ => false,
285        }
286    }
287
288    /// Checks if the value is the `JsonNode::Null` discriminant.
289    /// 
290    /// # Examples
291    /// 
292    /// ```
293    /// use json_node::JsonNode;
294    /// 
295    /// let null_value = JsonNode::Null;
296    /// let non_null_value = JsonNode::Integer(42);
297    /// 
298    /// assert!(null_value.is_null());
299    /// assert!(!non_null_value.is_null());
300    /// ```
301    pub fn is_null(&self) -> bool {
302        match self {
303            JsonNode::Null => true,
304            _ => false,
305        }
306    }
307
308    /// Extracts the inner `str` contained inside the node if it is the `JsonNode::String` discriminant.
309    /// 
310    /// # Examples
311    /// 
312    /// ```
313    /// use json_node::JsonNode;
314    /// 
315    /// let string_value = JsonNode::String("Hello World!".to_owned());
316    /// let non_string_value = JsonNode::Null;
317    /// 
318    /// assert_eq!(string_value.as_string(), Some("Hello World!"));
319    /// assert_eq!(non_string_value.as_string(), None);
320    /// ```
321    pub fn as_string(&self) -> Option<&str> {
322        match self {
323            JsonNode::String(value) => Some(value),
324            _ => None,
325        }
326    }
327
328    /// Extracts the inner `i64` contained inside the node if it is the `JsonNode::Integer` discriminant.
329    /// 
330    /// # Examples
331    /// 
332    /// ```
333    /// use json_node::JsonNode;
334    /// 
335    /// let integer_value = JsonNode::Integer(42);
336    /// let non_integer_value = JsonNode::Null;
337    /// 
338    /// assert_eq!(integer_value.as_integer(), Some(&42));
339    /// assert_eq!(non_integer_value.as_integer(), None);
340    /// ```
341    pub fn as_integer(&self) -> Option<&i64> {
342        match self {
343            JsonNode::Integer(value) => Some(value),
344            _ => None,
345        }
346    }
347
348    /// Extracts the inner `f64` contained inside the node if it is the `JsonNode::Float` discriminant.
349    /// 
350    /// # Examples
351    /// 
352    /// ```
353    /// use json_node::JsonNode;
354    /// 
355    /// let float_value = JsonNode::Float(3.14);
356    /// let non_float_value = JsonNode::Null;
357    /// 
358    /// assert_eq!(float_value.as_float(), Some(&3.14));
359    /// assert_eq!(non_float_value.as_float(), None);
360    /// ```
361    pub fn as_float(&self) -> Option<&f64> {
362        match self {
363            JsonNode::Float(value) => Some(value),
364            _ => None,
365        }
366    }
367
368    /// Extracts the inner `bool` contained inside the node if it is the `JsonNode::Boolean` discriminant.
369    /// 
370    /// # Examples
371    /// 
372    /// ```
373    /// use json_node::JsonNode;
374    /// 
375    /// let bool_value = JsonNode::Boolean(true);
376    /// let non_bool_value = JsonNode::Null;
377    /// 
378    /// assert_eq!(bool_value.as_boolean(), Some(&true));
379    /// assert_eq!(non_bool_value.as_boolean(), None);
380    /// ```
381    pub fn as_boolean(&self) -> Option<&bool> {
382        match self {
383            JsonNode::Boolean(value) => Some(value),
384            _ => None,
385        }
386    }
387
388    /// Extracts the inner `mut str` contained inside the node if it is the `JsonNode::String` discriminant.
389    /// 
390    /// # Examples
391    /// 
392    /// ```
393    /// use json_node::JsonNode;
394    /// 
395    /// let mut string_value = JsonNode::String("Hello World!".to_owned());
396    /// let mut non_string_value = JsonNode::Null;
397    /// 
398    /// assert_eq!(string_value.as_string_mut(), Some("Hello World!".to_string().as_mut_str()));
399    /// assert_eq!(non_string_value.as_string_mut(), None);
400    /// ```
401    pub fn as_string_mut(&mut self) -> Option<&mut str> {
402        match self {
403            JsonNode::String(value) => Some(value),
404            _ => None,
405        }
406    }
407
408    /// Extracts the inner `mut i64` contained inside the node if it is the `JsonNode::Integer` discriminant.
409    /// 
410    /// # Examples
411    /// 
412    /// ```
413    /// use json_node::JsonNode;
414    /// 
415    /// let mut integer_value = JsonNode::Integer(42);
416    /// let mut non_integer_value = JsonNode::Null;
417    /// 
418    /// assert_eq!(integer_value.as_integer_mut(), Some(&mut 42));
419    /// assert_eq!(non_integer_value.as_integer_mut(), None);
420    /// ```
421    pub fn as_integer_mut(&mut self) -> Option<&mut i64> {
422        match self {
423            JsonNode::Integer(value) => Some(value),
424            _ => None,
425        }
426    }
427
428    /// Extracts the inner `mut f64` contained inside the node if it is the `JsonNode::Float` discriminant.
429    /// 
430    /// # Examples
431    /// 
432    /// ```
433    /// use json_node::JsonNode;
434    /// 
435    /// let mut float_value = JsonNode::Float(3.14);
436    /// let mut non_float_value = JsonNode::Null;
437    /// 
438    /// assert_eq!(float_value.as_float_mut(), Some(&mut 3.14));
439    /// assert_eq!(non_float_value.as_float_mut(), None);
440    /// ```
441    pub fn as_float_mut(&mut self) -> Option<&mut f64> {
442        match self {
443            JsonNode::Float(value) => Some(value),
444            _ => None,
445        }
446    }
447
448    /// Extracts the inner `mut bool` contained inside the node if it is the `JsonNode::Boolean` discriminant.
449    /// 
450    /// # Examples
451    /// 
452    /// ```
453    /// use json_node::JsonNode;
454    /// 
455    /// let mut bool_value = JsonNode::Boolean(true);
456    /// let mut non_bool_value = JsonNode::Null;
457    /// 
458    /// assert_eq!(bool_value.as_boolean_mut(), Some(&mut true));
459    /// assert_eq!(non_bool_value.as_boolean_mut(), None);
460    /// ```
461    pub fn as_boolean_mut(&mut self) -> Option<&mut bool> {
462        match self {
463            JsonNode::Boolean(value) => Some(value),
464            _ => None,
465        }
466    }
467
468    /// Convert the node tree to a JSON string.
469    /// 
470    /// # Examples
471    /// 
472    /// ```
473    /// use json_node::JsonNode;
474    /// 
475    /// // Create a JsonNode tree.
476    /// let node_tree = JsonNode::Array(Vec::from([
477    ///     JsonNode::Integer(0),
478    ///     JsonNode::Float(0.5),
479    ///     JsonNode::Integer(1),
480    ///     JsonNode::Null,
481    ///     JsonNode::Boolean(false)
482    /// ]));
483    /// 
484    /// let json_string = node_tree.to_json_string();
485    /// 
486    /// assert_eq!(json_string, "[0,0.5,1,null,false]".to_owned());
487    /// ```
488    /// 
489    /// # Remarks
490    /// 
491    /// This function does zero formatting. The entire JSON string is returned without any spaces or new-lines.
492    pub fn to_json_string(&self) -> String {
493        match self {
494            JsonNode::String(value) => value.to_string().to_string().surround_with("\"", "\""),
495            JsonNode::Integer(value) => value.to_string(),
496            JsonNode::Float(value) => value.to_string(),
497            JsonNode::Boolean(value) => value.to_string(),
498            JsonNode::Null => String::from("null"),
499            JsonNode::Object(object) => object.to_json_string(),
500            JsonNode::Array(array) => {
501                array
502                .iter()
503                .map(|node| node.to_json_string())
504                .collect::<Vec<String>>()
505                .join(",")
506                .surround_with("[", "]")
507            },
508        }
509    }
510    
511}
512
513impl<'a> IntoIterator for &'a JsonNode {
514    type Item = &'a JsonNode;
515    type IntoIter = Iter<'a>;
516
517    /// Turns the node tree into an iterator which iterates over evey `JsonNode` in the tree in a depth first manner.
518    /// 
519    /// # Examples
520    /// 
521    /// ```
522    /// use json_node::JsonNode;
523    ///     
524    /// let node_tree = JsonNode::Array(Vec::from([
525    ///     JsonNode::Array(Vec::from([                     // First element is an array with the value `1` inside.
526    ///         JsonNode::Integer(1),
527    ///     ])),
528    ///     JsonNode::Integer(2),         // Second element is the value `2`.
529    ///     JsonNode::Array(Vec::from([
530    ///         JsonNode::Integer(3)      // Third element is an array with the value `3` inside.
531    ///     ]))
532    /// ]));
533    /// 
534    /// let sequence = node_tree.into_iter().collect::<Vec<&JsonNode>>();
535    /// 
536    /// let expected = vec![
537    ///     &JsonNode::Integer(1),
538    ///     &JsonNode::Integer(2),
539    ///     &JsonNode::Integer(3)
540    /// ];
541    /// 
542    /// assert_eq!(sequence, expected);
543    /// ```
544    fn into_iter(self) -> Self::IntoIter {
545        Iter {
546            node: Some(self),
547            array_index: None,
548            object_index: None,
549            child: None,
550        }
551    }
552}
553
554pub struct Iter<'a> {
555    node: Option<&'a JsonNode>,
556    array_index: Option<usize>,
557    object_index: Option<usize>,
558    child: Option<Box<Iter<'a>>>,
559}
560
561impl<'a> Iterator for Iter<'a> {
562    type Item = &'a JsonNode;
563
564    fn next(&mut self) -> Option<Self::Item> {
565        if let Some(iter) = &mut self.child {
566            if let Some(node) = iter.next() {
567                return Some(node);
568            }
569
570            self.child = None;
571        }
572
573        if let None = self.node {
574            return None; // Termination point for iteration. If the iterator has recursed, this allows the parent iterator to continue.
575        }
576
577        match self.node.unwrap() {
578            JsonNode::Array(nodes) => {
579                match self.array_index {
580                    Some(mut index) => {
581                        index = index + 1;
582                        self.array_index = Some(index);
583                        self.child = Some(Box::new(nodes[index].into_iter()));
584                        let next = self.next();
585
586                        if index == nodes.len() - 1 {
587                            self.array_index = None;
588                            self.node = None;
589                        }
590
591                        return next;
592                    },
593                    None => {
594                        self.array_index = Some(0);
595                        self.child = Some(Box::new(nodes[0].into_iter()));
596                        let next = self.next();
597
598                        if nodes.len() == 1 {
599                            self.array_index = None;
600                            self.node = None;
601                        }
602
603                        return next;
604                    },
605                }
606            },
607            JsonNode::Object(properties) => {
608                match self.object_index {
609                    Some(mut index) => {
610                        index = index + 1;
611                        self.object_index = Some(index);
612                        self.child = Some(Box::new(properties[index].1.into_iter()));
613                        let next = self.next();
614
615                        if index == properties.len() - 1 {
616                            self.object_index = None;
617                            self.node = None;
618                        }
619
620                        return next;
621                    },
622                    None => {
623                        self.object_index = Some(0);
624                        self.child = Some(Box::new(properties[0].1.into_iter()));
625                        let next = self.next();
626
627                        if properties.len() == 1 {
628                            self.object_index = None;
629                        }
630
631                        return next;
632                    },
633                }
634            },
635            _ => {
636                let node = self.node.unwrap();
637                self.node = None;
638                Some(node)
639            },
640        }
641    }
642}
643
644impl Display for JsonNode {
645    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
646        match self {
647            JsonNode::String(value) => write!(f, "{}", value),
648            JsonNode::Integer(value) => write!(f, "{}", value),
649            JsonNode::Float(value) => write!(f, "{}", value),
650            JsonNode::Boolean(value) => write!(f, "{}", value),
651            JsonNode::Null => write!(f, "null"),
652            JsonNode::Object(object) => write!(f, "{}", object.to_json_string()),
653            JsonNode::Array(array) => write!(f, "{}", {
654                array
655                .iter()
656                .map(|node| node.to_json_string())
657                .collect::<Vec<String>>()
658                .join(",")
659                .surround_with("[", "]")
660            }),
661        }
662    }
663}
664
665#[cfg(test)]
666mod tests {
667    use crate::JsonNode;
668
669    #[test]
670    fn iterate_works() {
671        let json = r#"
672        {
673            "name": "Jason",
674            "age": 30,
675            "isMale": true,
676            "height": 1.8,
677            "numbers": [1, 2, 3, 4, 5],
678            "children": [
679                {
680                    "name": "Jason Jr.",
681                    "age": 5,
682                    "isMale": true,
683                    "height": 1.2
684                },
685                {
686                    "name": "Jasmine",
687                    "age": 3,
688                    "isMale": false,
689                    "height": 1.1
690                }
691            ]
692        }"#;
693
694        let node = JsonNode::parse(json).unwrap();
695        for e in node.into_iter() {
696            println!("{:?}", e)
697        }
698    }
699}
700
701#[cfg(test)]
702mod doc_tests{
703
704    #[test]
705    fn parse_doc() {
706        use super::JsonNode;
707        
708        // Create a valid JSON string.
709        let json = "10";
710        // Manually create a tree with the expected structure and value.
711        let expected = JsonNode::Integer(10);
712
713        // Parse the json string into a node tree.
714        let node_tree = JsonNode::parse(json).unwrap();
715        
716        assert_eq!(node_tree, expected);
717    }
718
719    #[test]
720    fn into_iter() {
721        use crate::JsonNode;
722        
723        let node_tree = JsonNode::Array(Vec::from([
724            JsonNode::Array(Vec::from([                     // First element is an array with the value `1` inside.
725                JsonNode::Integer(1),
726            ])),
727            JsonNode::Integer(2),         // Second element is the value `2`.
728            JsonNode::Array(Vec::from([
729                JsonNode::Integer(3)      // Third element is an array with the value `3` inside.
730            ]))
731        ]));
732        
733        let sequence = node_tree.into_iter().collect::<Vec<&JsonNode>>();
734
735        let expected = vec![
736            &JsonNode::Integer(1),
737            &JsonNode::Integer(2),
738            &JsonNode::Integer(3)
739        ];
740
741        assert_eq!(sequence, expected);
742    }
743}