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, "\"")?;
156 for c in s.chars() {
157 match c {
158 '\\' => write!(out, "\\\\"),
159 '"' => write!(out, "\\\""),
160 c => write!(out, "{c}"),
161 }?;
162 }
163 write!(out, "\"")?;
164 }
165 Json::Number(n) => {
166 write!(out, "{n}")?;
167 }
168 Json::True => out.write_str("true")?,
169 Json::False => out.write_str("false")?,
170 Json::Null => out.write_str("null")?,
171 }
172 Ok(())
173 }
174 #[inline]
178 pub fn get(&self, key: impl AsRef<str>) -> Option<&Json> {
179 self.object().and_then(|obj| obj.get(key.as_ref()))
180 }
181 #[inline]
183 pub fn get_mut(&mut self, key: impl AsRef<str>) -> Option<&mut Json> {
184 self.object_mut().and_then(|obj| obj.get_mut(key.as_ref()))
185 }
186 #[inline]
190 pub fn nth(&self, i: usize) -> Option<&Json> {
191 self.array().and_then(|arr| arr.get(i))
192 }
193 #[inline]
195 pub fn nth_mut(&mut self, i: usize) -> Option<&mut Json> {
196 self.array_mut().and_then(|arr| arr.get_mut(i))
197 }
198
199 #[inline]
204 pub const fn number(&self) -> Option<f64> {
205 if let Json::Number(n) = self {
206 Some(*n)
207 } else {
208 None
209 }
210 }
211 #[inline]
218 pub const fn expect_number(&self) -> f64 {
219 self.number().unwrap()
220 }
221 #[inline]
226 pub const fn number_mut(&mut self) -> Option<&mut f64> {
227 if let Json::Number(n) = self {
228 Some(n)
229 } else {
230 None
231 }
232 }
233 #[inline]
241 pub const fn expect_number_mut(&mut self) -> &mut f64 {
242 self.number_mut().unwrap()
243 }
244
245 #[inline]
250 pub const fn string(&self) -> Option<&str> {
251 if let Json::String(s) = self {
252 Some(s)
253 } else {
254 None
255 }
256 }
257 #[inline]
264 pub const fn expect_string(&self) -> &str {
265 self.string().unwrap()
266 }
267 #[inline]
272 pub const fn string_mut(&mut self) -> Option<&mut str> {
273 if let Json::String(s) = self {
274 Some(s)
275 } else {
276 None
277 }
278 }
279 #[inline]
287 pub const fn expect_string_mut(&mut self) -> &mut str {
288 self.string_mut().unwrap()
289 }
290
291 #[inline]
294 pub const fn object(&self) -> Option<&Map<Box<str>, Json>> {
295 if let Json::Object(o) = self {
296 Some(o)
297 } else {
298 None
299 }
300 }
301 #[inline]
309 pub const fn expect_object(&self) -> &Map<Box<str>, Json> {
310 self.object().unwrap()
311 }
312 #[inline]
317 pub const fn object_mut(&mut self) -> Option<&mut Map<Box<str>, Json>> {
318 if let Json::Object(o) = self {
319 Some(o)
320 } else {
321 None
322 }
323 }
324 #[inline]
332 pub const fn expect_object_mut(&mut self) -> &mut Map<Box<str>, Json> {
333 self.object_mut().unwrap()
334 }
335
336 #[inline]
339 pub const fn array(&self) -> Option<&[Json]> {
340 if let Json::Array(o) = self {
341 Some(o)
342 } else {
343 None
344 }
345 }
346 #[inline]
353 pub const fn expect_array(&self) -> &[Json] {
354 self.array().unwrap()
355 }
356 #[inline]
359 pub const fn array_mut(&mut self) -> Option<&mut [Json]> {
360 if let Json::Array(o) = self {
361 Some(o)
362 } else {
363 None
364 }
365 }
366 #[inline]
373 pub const fn expect_array_mut(&mut self) -> &mut [Json] {
374 self.array_mut().unwrap()
375 }
376
377 #[inline]
380 pub const fn boolean(&self) -> Option<bool> {
381 if let Json::True = self {
382 Some(true)
383 } else if let Json::False = self {
384 Some(false)
385 } else {
386 None
387 }
388 }
389 #[inline]
397 pub const fn expect_boolean(&self) -> bool {
398 self.boolean().unwrap()
399 }
400
401 #[inline]
403 pub const fn is_null(&self) -> bool {
404 matches!(self, Json::Null)
405 }
406}
407
408impl fmt::Display for Json {
409 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
410 self.serialize(f)
411 }
412}
413
414macro_rules! from_num {
415 ( $( $nty:ty ),* ) => {
416 $(
417 impl From<$nty> for Json {
418 fn from(value: $nty) -> Self {
419 Self::Number(value.into())
420 }
421 }
422
423 impl AddAssign<$nty> for Json {
424 fn add_assign(&mut self, rhs: $nty) {
425 *self.expect_number_mut() += f64::from(rhs);
426 }
427 }
428
429 impl Add<$nty> for Json {
430 type Output = Json;
431
432 fn add(self, rhs: $nty) -> Self::Output {
433 Json::Number(self.expect_number() + f64::from(rhs))
434 }
435 }
436
437 impl SubAssign<$nty> for Json {
438 fn sub_assign(&mut self, rhs: $nty) {
439 *self.expect_number_mut() -= f64::from(rhs);
440 }
441 }
442
443 impl Sub<$nty> for Json {
444 type Output = Json;
445
446 fn sub(self, rhs: $nty) -> Self::Output {
447 Json::Number(self.expect_number() - f64::from(rhs))
448 }
449 }
450
451 impl MulAssign<$nty> for Json {
452 fn mul_assign(&mut self, rhs: $nty) {
453 *self.expect_number_mut() *= f64::from(rhs);
454 }
455 }
456
457 impl Mul<$nty> for Json {
458 type Output = Json;
459
460 fn mul(self, rhs: $nty) -> Self::Output {
461 Json::Number(self.expect_number() * f64::from(rhs))
462 }
463 }
464
465 impl DivAssign<$nty> for Json {
466 fn div_assign(&mut self, rhs: $nty) {
467 *self.expect_number_mut() /= f64::from(rhs);
468 }
469 }
470
471 impl Div<$nty> for Json {
472 type Output = Json;
473
474 fn div(self, rhs: $nty) -> Self::Output {
475 Json::Number(self.expect_number() / f64::from(rhs))
476 }
477 }
478 )*
479 };
480}
481
482from_num!(f64, f32, i32, i16, u16, u8);
483
484impl From<String> for Json {
485 fn from(value: String) -> Self {
486 Self::String(value.into_boxed_str())
487 }
488}
489
490impl From<Box<str>> for Json {
491 fn from(value: Box<str>) -> Self {
492 Self::String(value)
493 }
494}
495
496impl<'a> From<&'a str> for Json {
497 fn from(value: &'a str) -> Self {
498 Self::String(value.into())
499 }
500}
501
502impl From<Vec<Json>> for Json {
503 fn from(value: Vec<Json>) -> Self {
504 Self::Array(value.into())
505 }
506}
507
508impl From<Map<Box<str>, Json>> for Json {
509 fn from(value: Map<Box<str>, Json>) -> Self {
510 Self::Object(value)
511 }
512}
513
514impl From<bool> for Json {
515 fn from(value: bool) -> Self {
516 if value { Json::True } else { Json::False }
517 }
518}
519
520impl Index<&str> for Json {
521 type Output = Json;
522
523 fn index(&self, index: &str) -> &Self::Output {
524 self.get(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 IndexMut<&str> for Json {
531 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
532 self.get_mut(index).unwrap_or_else(|| {
533 panic!("Attemp to index a json element that doesn't contain the given key: '{index}'")
534 })
535 }
536}
537
538impl Index<usize> for Json {
539 type Output = Json;
540
541 fn index(&self, index: usize) -> &Self::Output {
542 self.nth(index).unwrap_or_else(|| {
543 panic!("Attemp to index a json element that can't be indexed by {index}")
544 })
545 }
546}
547
548impl IndexMut<usize> for Json {
549 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
550 self.nth_mut(index).unwrap_or_else(|| {
551 panic!("Attemp to index a json element that can't be indexed by {index}")
552 })
553 }
554}
555
556#[doc(hidden)]
557pub use prelude::Map;
558
559#[macro_export]
577macro_rules! json {
578 ( $lit:literal ) => {
579 $crate::Json::from( $lit )
580 };
581 ( { $e:expr } ) => {
582 $crate::Json::from( $e )
583 };
584 ( [ $( $e:tt ),* $(,)? ] ) => {
585 $crate::Json::from(
586 vec![
587 $(
588 json!($e)
589 ),*
590 ]
591 )
592 };
593 ( { $( $key:literal : $val:tt ),* $(,)? } ) => {
594 {
595 let mut map = $crate::Map::new();
596 $( map.insert($key .into(), json!($val) ); )*
597 $crate::Json::from ( map )
598 }
599 };
600 ( null ) => {
601 $crate::Json::Null
602 }
603}