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}