json/
lib.rs

1//! Json parser
2//!
3//! # Example
4//! ```
5//! use json::Json;
6//!
7//! let j = Json::deserialize(r#"{
8//!     "array" : [ 1, 2, "3", null ],
9//!     "true" : true,
10//!     "nested" : {
11//!         "inner" : []
12//!     }
13//! }"#).unwrap();
14//!
15//! let Json::Object(map) = j else { panic!() };
16//! assert!(
17//!     matches!(
18//!         map.get("true"),
19//!         Some(Json::True)));
20//! ```
21
22#![warn(clippy::pedantic)]
23#![allow(
24    clippy::missing_errors_doc,
25    clippy::must_use_candidate
26)]
27
28#![cfg_attr(not(feature = "std"), no_std)]
29
30#[macro_use]
31extern crate alloc;
32
33mod prelude {
34    pub use alloc::string::ToString;
35    pub use core::fmt;
36    pub use alloc::vec::Vec;
37    pub use alloc::borrow::Cow;
38    pub use alloc::boxed::Box;
39
40    #[cfg(feature = "std")]
41    pub type Map<K,V> = std::collections::HashMap<K,V>;
42
43    #[cfg(not(feature = "std"))]
44    pub type Map<K,V> = alloc::collections::BTreeMap<K,V>;
45}
46
47use core::ops::{Add, AddAssign, Index, IndexMut, Sub, SubAssign, Div, DivAssign, Mul, MulAssign};
48
49use prelude::*;
50
51mod lexer;
52mod parser;
53
54#[cfg(feature = "bindings")]
55pub mod export;
56
57mod error;
58
59type Result<T> = core::result::Result<T,error::Error>;
60
61/// Represents a JSON object
62#[derive(Debug,PartialEq)]
63pub enum Json {
64    Array(Box<[Json]>),
65    Object(Map<Box<str>,Json>),
66    String(Box<str>),
67    Number(f64),
68    True, False, Null,
69}
70
71/// Configures the JSON parser
72#[repr(C)]
73#[derive(Clone,Copy)]
74pub struct JsonConfig {
75    /// Max depth for nested objects
76    pub max_depth: u32,
77    /// Recover from errors.
78    /// For example, trailing commas on objects
79    /// are not allowed, but this flag makes
80    /// the parser skip them.
81    pub recover_from_errors: bool,
82}
83
84/// Default config used by [`Json::deserialize`]
85const DEFAULT_CONFIG: JsonConfig = JsonConfig {
86    max_depth: u32::MAX,
87    recover_from_errors: false,
88};
89
90impl Default for JsonConfig {
91    fn default() -> Self { DEFAULT_CONFIG }
92}
93
94impl Json {
95    /// Deserializes the given string into a [Json] object
96    ///
97    /// ## Configuration used
98    /// [`max_depth`](JsonConfig::max_depth) = [`u32::MAX`]
99    ///
100    /// [`recover_from_errors`](JsonConfig::recover_from_errors) = false
101    #[inline]
102    pub fn deserialize(text: impl AsRef<str>) -> Result<Json> {
103        Json::deserialize_with_config(text, DEFAULT_CONFIG)
104    }
105    /// Deserializes the given string into a [Json] object
106    /// using the given [`JsonConfig`]
107    pub fn deserialize_with_config(text: impl AsRef<str>, conf: JsonConfig) -> Result<Json> {
108        let text = text.as_ref();
109        let tokens = lexer::tokenize(text)?;
110        parser::parse(text, &tokens, conf)
111    }
112    /// Serializes the JSON object into a [`fmt::Write`]
113    pub fn serialize(&self, out: &mut dyn fmt::Write) -> fmt::Result {
114        match self {
115            Json::Array(elements) => {
116                out.write_char('[')?;
117                for i in 0..elements.len() {
118                    elements[i].serialize(out)?;
119                    if i < elements.len() -1 {
120                        out.write_char(',')?;
121                    }
122                }
123                out.write_char(']')?;
124            },
125            Json::Object(obj) => {
126                out.write_char('{')?;
127                let mut first = true;
128                for (k,v) in obj {
129                    if !first {
130                        out.write_char(',')?;
131                    }
132                    first = false;
133                    write!(out, "\"{k}\":")?;
134                    v.serialize(out)?;
135                }
136                out.write_char('}')?;
137            },
138            Json::String(s) => { write!(out, "\"{s}\"")?; },
139            Json::Number(n) => { write!(out, "{n}")?; },
140            Json::True => { out.write_str("true")? },
141            Json::False => { out.write_str("false")? },
142            Json::Null => { out.write_str("null")? },
143        }
144        Ok(())
145    }
146    /// Attempts to get a value of the given json object.
147    /// If the json enum is not an Object variant, or if
148    /// it doesn't contain the key, returns None
149    #[inline]
150    pub fn get(&self, key: impl AsRef<str>) -> Option<&Json> {
151        self.object().and_then(|obj| obj.get(key.as_ref()))
152    }
153    /// Same as [get](Self::get), but with a mutable reference
154    #[inline]
155    pub fn get_mut(&mut self, key: impl AsRef<str>) -> Option<&mut Json> {
156        self.object_mut().and_then(|obj| obj.get_mut(key.as_ref()))
157    }
158    /// Attempts to get a value of the given json array.
159    /// If the json enum is not an Array variant, or if
160    /// it doesn't contain the key, returns None
161    #[inline]
162    pub fn nth(&self, i: usize) -> Option<&Json> {
163        self.array().and_then(|arr| arr.get(i))
164    }
165    /// Same as [nth](Self::nth), but with a mutable reference
166    #[inline]
167    pub fn nth_mut(&mut self, i: usize) -> Option<&mut Json> {
168        self.array_mut().and_then(|arr| arr.get_mut(i))
169    }
170
171    /// Attempts to get the inner [`Number`] of the json
172    /// object, if it is a [`Number`] variant
173    ///
174    /// [`Number`]: Json::Number
175    #[inline]
176    pub fn number(&self) -> Option<f64> {
177        if let Json::Number(n) = self {
178            Some(*n)
179        } else { None }
180    }
181    /// Expects the json object to be a [`Number`] variant
182    ///
183    /// # Panics
184    /// If the json object is not a [`Number`] variant
185    ///
186    /// [`Number`]: Json::Number
187    #[inline]
188    pub fn expect_number(&self) -> f64 {
189        self.number().unwrap()
190    }
191    /// Attempts to get a mutable reference to the inner [`Number`]
192    /// of the json object, if it is a [`Number`] variant
193    ///
194    /// [`Number`]: Json::Number
195    #[inline]
196    pub fn number_mut(&mut self) -> Option<&mut f64> {
197        if let Json::Number(n) = self {
198            Some(n)
199        } else { None }
200    }
201    /// Expects the json object to be a [`Number`] variant
202    /// and gets a mutable reference to the inner number.
203    ///
204    /// # Panics
205    /// If the json object is not a [`Number`] variant
206    ///
207    /// [`Number`]: Json::Number
208    #[inline]
209    pub fn expect_number_mut(&mut self) -> &mut f64 {
210        self.number_mut().unwrap()
211    }
212
213    /// Attempts to get the inner [`String`] of the json
214    /// object, if it is a [`String`] variant
215    ///
216    /// [`String`]: Json::String
217    #[inline]
218    pub fn string(&self) -> Option<&str> {
219        if let Json::String(s) = self {
220            Some(s)
221        } else { None }
222    }
223    /// Expects the json object to be a [`String`] variant
224    ///
225    /// # Panics
226    /// If the json object is not a [`String`] variant
227    ///
228    /// [`String`]: Json::String
229    #[inline]
230    pub fn expect_string(&self) -> &str {
231        self.string().unwrap()
232    }
233    /// Attempts to get a mutable reference to the inner
234    /// [`String`] of the json object, if it is a [`String`] variant
235    ///
236    /// [`String`]: Json::String
237    #[inline]
238    pub fn string_mut(&mut self) -> Option<&mut str> {
239        if let Json::String(s) = self {
240            Some(s)
241        } else { None }
242    }
243    /// Expects the json object to be a [`String`] variant
244    /// and gets a reference to the inner string
245    ///
246    /// # Panics
247    /// If the json object is not a [`String`] variant
248    ///
249    /// [`String`]: Json::String
250    #[inline]
251    pub fn expect_string_mut(&mut self) -> &mut str {
252        self.string_mut().unwrap()
253    }
254
255    /// Attempts to get the inner Object of the json object, if
256    /// it is an Object variant
257    #[inline]
258    pub fn object(&self) -> Option<&Map<Box<str>,Json>> {
259        if let Json::Object(o) = self {
260            Some(o)
261        } else { None }
262    }
263    /// Expects the json object to be a [`Object`] variant
264    /// and gets a reference to the inner object
265    ///
266    /// # Panics
267    /// If the json object is not a [`Object`] variant
268    ///
269    /// [`Object`]: Json::Object
270    #[inline]
271    pub fn expect_object(&self) -> &Map<Box<str>,Json> {
272        self.object().unwrap()
273    }
274    /// Attempts to get a mutable reference to the inner [`Object`] of
275    /// the json element, if it is an [`Object`] variant
276    ///
277    /// [`Object`]: Json::Object
278    #[inline]
279    pub fn object_mut(&mut self) -> Option<&mut Map<Box<str>,Json>> {
280        if let Json::Object(o) = self {
281            Some(o)
282        } else { None }
283    }
284    /// Expects the json object to be a [`Object`] variant
285    /// and gets a mutable reference to the inner object
286    ///
287    /// # Panics
288    /// If the json object is not a [`Object`] variant
289    ///
290    /// [`Object`]: Json::Object
291    #[inline]
292    pub fn expect_object_mut(&mut self) -> &mut Map<Box<str>,Json> {
293        self.object_mut().unwrap()
294    }
295
296    /// Attempts to get the inner Array of the json object, if
297    /// it is an Array variant
298    #[inline]
299    pub fn array(&self) -> Option<&[Json]> {
300        if let Json::Array(o) = self {
301            Some(o)
302        } else { None }
303    }
304    /// Expects the json object to be a [`Array`] variant
305    ///
306    /// # Panics
307    /// If the json object is not a [`Array`] variant
308    ///
309    /// [`Array`]: Json::Array
310    #[inline]
311    pub fn expect_array(&self) -> &[Json] {
312        self.array().unwrap()
313    }
314    /// Attempts to get the inner Array of the json object, if
315    /// it is an Array variant
316    #[inline]
317    pub fn array_mut(&mut self) -> Option<&mut [Json]> {
318        if let Json::Array(o) = self {
319            Some(o)
320        } else { None }
321    }
322    /// Expects the json object to be a [`Array`] variant
323    ///
324    /// # Panics
325    /// If the json object is not a [`Array`] variant
326    ///
327    /// [`Array`]: Json::Array
328    #[inline]
329    pub fn expect_array_mut(&mut self) -> &mut [Json] {
330        self.array_mut().unwrap()
331    }
332
333    /// Attempts to get the inner boolean value of the json object, if
334    /// it is a True or False variant
335    #[inline]
336    pub fn boolean(&self) -> Option<bool> {
337        if let Json::True = self {
338            Some(true)
339        } else if let Json::False = self {
340            Some(false)
341        } else { None }
342    }
343    /// Expects the json object to be a [`True`] or [`False`] variant
344    ///
345    /// # Panics
346    /// If the json object is not a [`True`] or [`False`] variant
347    ///
348    /// [`True`]: Json::True
349    /// [`False`]: Json::False
350    #[inline]
351    pub fn expect_boolean(&self) -> bool {
352        self.boolean().unwrap()
353    }
354
355    /// Returns true if the json is a Nil variant
356    #[inline]
357    pub fn is_null(&self) -> bool {
358        matches!(self,Json::Null)
359    }
360}
361
362impl fmt::Display for Json {
363    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
364        self.serialize(f)
365    }
366}
367
368macro_rules! from_num {
369    ( $( $nty:ty ),* ) => {
370        $(
371            impl From<$nty> for Json {
372                fn from(value: $nty) -> Self {
373                    Self::Number(value.into())
374                }
375            }
376
377            impl AddAssign<$nty> for Json {
378                fn add_assign(&mut self, rhs: $nty) {
379                    *self.expect_number_mut() += f64::from(rhs);
380                }
381            }
382
383            impl Add<$nty> for Json {
384                type Output = Json;
385
386                fn add(self, rhs: $nty) -> Self::Output {
387                    Json::Number(self.expect_number() + f64::from(rhs))
388                }
389            }
390
391            impl SubAssign<$nty> for Json {
392                fn sub_assign(&mut self, rhs: $nty) {
393                    *self.expect_number_mut() -= f64::from(rhs);
394                }
395            }
396
397            impl Sub<$nty> for Json {
398                type Output = Json;
399
400                fn sub(self, rhs: $nty) -> Self::Output {
401                    Json::Number(self.expect_number() - f64::from(rhs))
402                }
403            }
404
405            impl MulAssign<$nty> for Json {
406                fn mul_assign(&mut self, rhs: $nty) {
407                    *self.expect_number_mut() *= f64::from(rhs);
408                }
409            }
410
411            impl Mul<$nty> for Json {
412                type Output = Json;
413
414                fn mul(self, rhs: $nty) -> Self::Output {
415                    Json::Number(self.expect_number() * f64::from(rhs))
416                }
417            }
418
419            impl DivAssign<$nty> for Json {
420                fn div_assign(&mut self, rhs: $nty) {
421                    *self.expect_number_mut() /= f64::from(rhs);
422                }
423            }
424
425            impl Div<$nty> for Json {
426                type Output = Json;
427
428                fn div(self, rhs: $nty) -> Self::Output {
429                    Json::Number(self.expect_number() / f64::from(rhs))
430                }
431            }
432        )*
433    };
434}
435
436from_num!(f64,f32,i32,i16,u16,u8);
437
438impl From<String> for Json {
439    fn from(value: String) -> Self {
440        Self::String(value.into_boxed_str())
441    }
442}
443
444impl From<Box<str>> for Json {
445    fn from(value: Box<str>) -> Self {
446        Self::String(value)
447    }
448}
449
450impl<'a> From<&'a str> for Json {
451    fn from(value: &'a str) -> Self {
452        Self::String(value.into())
453    }
454}
455
456impl From<Vec<Json>> for Json {
457    fn from(value: Vec<Json>) -> Self {
458        Self::Array(value.into())
459    }
460}
461
462impl From<Map<Box<str>,Json>> for Json {
463    fn from(value: Map<Box<str>,Json>) -> Self {
464        Self::Object(value)
465    }
466}
467
468impl From<bool> for Json {
469    fn from(value: bool) -> Self {
470        if value { Json::True } else { Json::False }
471    }
472}
473
474impl Index<&str> for Json {
475    type Output = Json;
476
477    fn index(&self, index: &str) -> &Self::Output {
478        self.get(index).unwrap_or_else(|| {
479            panic!("Attemp to index a json element that doesn't contain the given key: '{index}'")
480        })
481    }
482}
483
484impl IndexMut<&str> for Json {
485    fn index_mut(&mut self, index: &str) -> &mut Self::Output {
486        self.get_mut(index).unwrap_or_else(|| {
487            panic!("Attemp to index a json element that doesn't contain the given key: '{index}'")
488        })
489    }
490}
491
492impl Index<usize> for Json {
493    type Output = Json;
494
495    fn index(&self, index: usize) -> &Self::Output {
496        self.nth(index).unwrap_or_else(|| {
497            panic!("Attemp to index a json element that can't be indexed by {index}")
498        })
499    }
500}
501
502impl IndexMut<usize> for Json {
503    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
504        self.nth_mut(index).unwrap_or_else(|| {
505            panic!("Attemp to index a json element that can't be indexed by {index}")
506        })
507    }
508}
509
510#[doc(hidden)]
511pub use prelude::Map;
512
513/// Builds a [Json] object
514///
515/// # Example
516/// ```
517/// use json::json;
518///
519/// let j = json!({
520///     "hello" : ["w", 0, "r", "ld"],
521///     "array" : [
522///         { "key" : "val" },
523///         12.21,
524///         null,
525///         true,
526///         false
527///     ]
528/// });
529/// ```
530#[macro_export]
531macro_rules! json {
532    ( $lit:literal ) => {
533        $crate::Json::from( $lit )
534    };
535    ( [ $( $e:tt ),* ] ) => {
536        $crate::Json::from(
537            vec![
538                $(
539                    json!($e)
540                ),*
541            ]
542        )
543    };
544    ( { $( $key:literal : $val:tt ),*  } ) => {
545        {
546            let mut map = $crate::Map::new();
547            $( map.insert($key .into(), json!($val) );  )*
548            $crate::Json::from ( map )
549        }
550    };
551    ( null ) => {
552        $crate::Json::Null
553    }
554}