1#![warn(clippy::pedantic)]
37#![allow(clippy::missing_errors_doc, clippy::must_use_candidate)]
38#![cfg_attr(not(feature = "std"), no_std)]
39
40#[macro_use]
41extern crate alloc;
42
43mod prelude {
44 pub use alloc::borrow::Cow;
45 pub use alloc::boxed::Box;
46 pub use alloc::string::{String, ToString};
47 pub use alloc::vec::Vec;
48 pub use core::fmt;
49
50 #[cfg(feature = "std")]
51 pub type Map<K, V> = std::collections::HashMap<K, V>;
52
53 #[cfg(not(feature = "std"))]
54 pub type Map<K, V> = alloc::collections::BTreeMap<K, V>;
55}
56
57use core::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign};
58
59use prelude::*;
60
61mod lexer;
62mod parser;
63
64#[cfg(feature = "bindings")]
65pub mod export;
66
67mod error;
68
69type Result<T> = core::result::Result<T, error::Error>;
70
71#[derive(Debug, PartialEq)]
73pub enum Json {
74 Array(Box<[Json]>),
75 Object(Map<Box<str>, Json>),
76 String(Box<str>),
77 Number(f64),
78 True,
79 False,
80 Null,
81}
82
83#[repr(C)]
85#[derive(Clone, Copy)]
86pub struct JsonConfig {
87 pub max_depth: u32,
89
90 pub allow_trailing_commas: bool,
92
93 pub allow_comments: bool,
95}
96
97const DEFAULT_CONFIG: JsonConfig = JsonConfig {
99 max_depth: u32::MAX,
100 allow_trailing_commas: false,
101 allow_comments: false,
102};
103
104impl Default for JsonConfig {
105 fn default() -> Self {
106 DEFAULT_CONFIG
107 }
108}
109
110impl Json {
111 #[inline]
118 pub fn deserialize(text: impl AsRef<str>) -> Result<Json> {
119 Json::deserialize_with_config(text, DEFAULT_CONFIG)
120 }
121 pub fn deserialize_with_config(text: impl AsRef<str>, conf: JsonConfig) -> Result<Json> {
124 let text = text.as_ref();
125 let tokens = lexer::tokenize(text, conf)?;
126 parser::parse(text, &tokens, conf)
127 }
128 pub fn serialize(&self, out: &mut dyn fmt::Write) -> fmt::Result {
130 match self {
131 Json::Array(elements) => {
132 out.write_char('[')?;
133 for i in 0..elements.len() {
134 elements[i].serialize(out)?;
135 if i < elements.len() - 1 {
136 out.write_char(',')?;
137 }
138 }
139 out.write_char(']')?;
140 }
141 Json::Object(obj) => {
142 out.write_char('{')?;
143 let mut first = true;
144 for (k, v) in obj {
145 if !first {
146 out.write_char(',')?;
147 }
148 first = false;
149 write!(out, "\"{k}\":")?;
150 v.serialize(out)?;
151 }
152 out.write_char('}')?;
153 }
154 Json::String(s) => {
155 write!(out, "\"{s}\"")?;
156 }
157 Json::Number(n) => {
158 write!(out, "{n}")?;
159 }
160 Json::True => out.write_str("true")?,
161 Json::False => out.write_str("false")?,
162 Json::Null => out.write_str("null")?,
163 }
164 Ok(())
165 }
166 #[inline]
170 pub fn get(&self, key: impl AsRef<str>) -> Option<&Json> {
171 self.object().and_then(|obj| obj.get(key.as_ref()))
172 }
173 #[inline]
175 pub fn get_mut(&mut self, key: impl AsRef<str>) -> Option<&mut Json> {
176 self.object_mut().and_then(|obj| obj.get_mut(key.as_ref()))
177 }
178 #[inline]
182 pub fn nth(&self, i: usize) -> Option<&Json> {
183 self.array().and_then(|arr| arr.get(i))
184 }
185 #[inline]
187 pub fn nth_mut(&mut self, i: usize) -> Option<&mut Json> {
188 self.array_mut().and_then(|arr| arr.get_mut(i))
189 }
190
191 #[inline]
196 pub const fn number(&self) -> Option<f64> {
197 if let Json::Number(n) = self {
198 Some(*n)
199 } else {
200 None
201 }
202 }
203 #[inline]
210 pub const fn expect_number(&self) -> f64 {
211 self.number().unwrap()
212 }
213 #[inline]
218 pub const fn number_mut(&mut self) -> Option<&mut f64> {
219 if let Json::Number(n) = self {
220 Some(n)
221 } else {
222 None
223 }
224 }
225 #[inline]
233 pub const fn expect_number_mut(&mut self) -> &mut f64 {
234 self.number_mut().unwrap()
235 }
236
237 #[inline]
242 pub const fn string(&self) -> Option<&str> {
243 if let Json::String(s) = self {
244 Some(s)
245 } else {
246 None
247 }
248 }
249 #[inline]
256 pub const fn expect_string(&self) -> &str {
257 self.string().unwrap()
258 }
259 #[inline]
264 pub const fn string_mut(&mut self) -> Option<&mut str> {
265 if let Json::String(s) = self {
266 Some(s)
267 } else {
268 None
269 }
270 }
271 #[inline]
279 pub const fn expect_string_mut(&mut self) -> &mut str {
280 self.string_mut().unwrap()
281 }
282
283 #[inline]
286 pub const fn object(&self) -> Option<&Map<Box<str>, Json>> {
287 if let Json::Object(o) = self {
288 Some(o)
289 } else {
290 None
291 }
292 }
293 #[inline]
301 pub const fn expect_object(&self) -> &Map<Box<str>, Json> {
302 self.object().unwrap()
303 }
304 #[inline]
309 pub const fn object_mut(&mut self) -> Option<&mut Map<Box<str>, Json>> {
310 if let Json::Object(o) = self {
311 Some(o)
312 } else {
313 None
314 }
315 }
316 #[inline]
324 pub const fn expect_object_mut(&mut self) -> &mut Map<Box<str>, Json> {
325 self.object_mut().unwrap()
326 }
327
328 #[inline]
331 pub const fn array(&self) -> Option<&[Json]> {
332 if let Json::Array(o) = self {
333 Some(o)
334 } else {
335 None
336 }
337 }
338 #[inline]
345 pub const fn expect_array(&self) -> &[Json] {
346 self.array().unwrap()
347 }
348 #[inline]
351 pub const fn array_mut(&mut self) -> Option<&mut [Json]> {
352 if let Json::Array(o) = self {
353 Some(o)
354 } else {
355 None
356 }
357 }
358 #[inline]
365 pub const fn expect_array_mut(&mut self) -> &mut [Json] {
366 self.array_mut().unwrap()
367 }
368
369 #[inline]
372 pub const fn boolean(&self) -> Option<bool> {
373 if let Json::True = self {
374 Some(true)
375 } else if let Json::False = self {
376 Some(false)
377 } else {
378 None
379 }
380 }
381 #[inline]
389 pub const fn expect_boolean(&self) -> bool {
390 self.boolean().unwrap()
391 }
392
393 #[inline]
395 pub const fn is_null(&self) -> bool {
396 matches!(self, Json::Null)
397 }
398}
399
400impl fmt::Display for Json {
401 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402 self.serialize(f)
403 }
404}
405
406macro_rules! from_num {
407 ( $( $nty:ty ),* ) => {
408 $(
409 impl From<$nty> for Json {
410 fn from(value: $nty) -> Self {
411 Self::Number(value.into())
412 }
413 }
414
415 impl AddAssign<$nty> for Json {
416 fn add_assign(&mut self, rhs: $nty) {
417 *self.expect_number_mut() += f64::from(rhs);
418 }
419 }
420
421 impl Add<$nty> for Json {
422 type Output = Json;
423
424 fn add(self, rhs: $nty) -> Self::Output {
425 Json::Number(self.expect_number() + f64::from(rhs))
426 }
427 }
428
429 impl SubAssign<$nty> for Json {
430 fn sub_assign(&mut self, rhs: $nty) {
431 *self.expect_number_mut() -= f64::from(rhs);
432 }
433 }
434
435 impl Sub<$nty> for Json {
436 type Output = Json;
437
438 fn sub(self, rhs: $nty) -> Self::Output {
439 Json::Number(self.expect_number() - f64::from(rhs))
440 }
441 }
442
443 impl MulAssign<$nty> for Json {
444 fn mul_assign(&mut self, rhs: $nty) {
445 *self.expect_number_mut() *= f64::from(rhs);
446 }
447 }
448
449 impl Mul<$nty> for Json {
450 type Output = Json;
451
452 fn mul(self, rhs: $nty) -> Self::Output {
453 Json::Number(self.expect_number() * f64::from(rhs))
454 }
455 }
456
457 impl DivAssign<$nty> for Json {
458 fn div_assign(&mut self, rhs: $nty) {
459 *self.expect_number_mut() /= f64::from(rhs);
460 }
461 }
462
463 impl Div<$nty> for Json {
464 type Output = Json;
465
466 fn div(self, rhs: $nty) -> Self::Output {
467 Json::Number(self.expect_number() / f64::from(rhs))
468 }
469 }
470 )*
471 };
472}
473
474from_num!(f64, f32, i32, i16, u16, u8);
475
476impl From<String> for Json {
477 fn from(value: String) -> Self {
478 Self::String(value.into_boxed_str())
479 }
480}
481
482impl From<Box<str>> for Json {
483 fn from(value: Box<str>) -> Self {
484 Self::String(value)
485 }
486}
487
488impl<'a> From<&'a str> for Json {
489 fn from(value: &'a str) -> Self {
490 Self::String(value.into())
491 }
492}
493
494impl From<Vec<Json>> for Json {
495 fn from(value: Vec<Json>) -> Self {
496 Self::Array(value.into())
497 }
498}
499
500impl From<Map<Box<str>, Json>> for Json {
501 fn from(value: Map<Box<str>, Json>) -> Self {
502 Self::Object(value)
503 }
504}
505
506impl From<bool> for Json {
507 fn from(value: bool) -> Self {
508 if value { Json::True } else { Json::False }
509 }
510}
511
512impl Index<&str> for Json {
513 type Output = Json;
514
515 fn index(&self, index: &str) -> &Self::Output {
516 self.get(index).unwrap_or_else(|| {
517 panic!("Attemp to index a json element that doesn't contain the given key: '{index}'")
518 })
519 }
520}
521
522impl IndexMut<&str> for Json {
523 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
524 self.get_mut(index).unwrap_or_else(|| {
525 panic!("Attemp to index a json element that doesn't contain the given key: '{index}'")
526 })
527 }
528}
529
530impl Index<usize> for Json {
531 type Output = Json;
532
533 fn index(&self, index: usize) -> &Self::Output {
534 self.nth(index).unwrap_or_else(|| {
535 panic!("Attemp to index a json element that can't be indexed by {index}")
536 })
537 }
538}
539
540impl IndexMut<usize> for Json {
541 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
542 self.nth_mut(index).unwrap_or_else(|| {
543 panic!("Attemp to index a json element that can't be indexed by {index}")
544 })
545 }
546}
547
548#[doc(hidden)]
549pub use prelude::Map;
550
551#[macro_export]
569macro_rules! json {
570 ( $lit:literal ) => {
571 $crate::Json::from( $lit )
572 };
573 ( { $e:expr } ) => {
574 $crate::Json::from( $e )
575 };
576 ( [ $( $e:tt ),* $(,)? ] ) => {
577 $crate::Json::from(
578 vec![
579 $(
580 json!($e)
581 ),*
582 ]
583 )
584 };
585 ( { $( $key:literal : $val:tt ),* $(,)? } ) => {
586 {
587 let mut map = $crate::Map::new();
588 $( map.insert($key .into(), json!($val) ); )*
589 $crate::Json::from ( map )
590 }
591 };
592 ( null ) => {
593 $crate::Json::Null
594 }
595}