nanoserde/
serde_json.rs

1use core::error::Error;
2use core::str::Chars;
3
4use alloc::boxed::Box;
5use alloc::collections::{BTreeMap, BTreeSet, LinkedList};
6use alloc::format;
7use alloc::string::{String, ToString};
8use alloc::vec::Vec;
9
10/// The internal state of a JSON serialization.
11#[non_exhaustive]
12pub struct SerJsonState {
13    pub out: String,
14}
15
16impl SerJsonState {
17    pub fn new(out: String) -> Self {
18        Self { out }
19    }
20
21    pub fn indent(&mut self, _d: usize) {
22        //for _ in 0..d {
23        //    self.out.push_str("    ");
24        //}
25    }
26
27    pub fn field(&mut self, d: usize, field: &str) {
28        self.indent(d);
29        self.out.push('"');
30        self.out.push_str(field);
31        self.out.push('"');
32        self.out.push(':');
33    }
34
35    pub fn label(&mut self, label: &str) {
36        self.out.push('"');
37        self.out.push_str(label);
38        self.out.push('"');
39    }
40
41    pub fn conl(&mut self) {
42        self.out.push(',')
43    }
44
45    pub fn st_pre(&mut self) {
46        self.out.push('{');
47    }
48
49    pub fn st_post(&mut self, d: usize) {
50        self.indent(d);
51        self.out.push('}');
52    }
53}
54
55/// A trait for objects that can be serialized to JSON.
56pub trait SerJson {
57    /// Serialize Self to a JSON string.
58    ///
59    /// This is a convenient wrapper around `ser_json`.
60    fn serialize_json(&self) -> String {
61        let mut s = SerJsonState { out: String::new() };
62        self.ser_json(0, &mut s);
63        s.out
64    }
65
66    /// Serialize Self to a JSON string.
67    ///
68    /// ```rust
69    /// # use nanoserde::*;
70    /// let mut s = SerJsonState::new(String::new());
71    /// 42u32.ser_json(0, &mut s);
72    /// assert_eq!(s.out, "42");
73    /// ```
74    fn ser_json(&self, d: usize, s: &mut SerJsonState);
75}
76
77/// A trait for objects that can be deserialized from JSON.
78pub trait DeJson: Sized {
79    /// Parse Self from the input string.
80    ///
81    /// This is a convenient wrapper around `de_json`.
82    fn deserialize_json(input: &str) -> Result<Self, DeJsonErr> {
83        let mut state = DeJsonState::default();
84        let mut chars = input.chars();
85        state.next(&mut chars);
86        state.next_tok(&mut chars)?;
87        DeJson::de_json(&mut state, &mut chars)
88    }
89
90    /// Parse Self from the input string.
91    ///
92    /// ```rust
93    /// # use nanoserde::*;
94    /// let mut state = DeJsonState::default();
95    /// let mut chars = "42".chars();
96    /// state.next(&mut chars);
97    /// state.next_tok(&mut chars).unwrap();
98    /// let out = u32::de_json(&mut state, &mut chars).unwrap();
99    /// assert_eq!(out, 42);
100    /// ```
101    fn de_json(state: &mut DeJsonState, input: &mut Chars) -> Result<Self, DeJsonErr>;
102}
103
104/// A JSON parsed token.
105#[derive(PartialEq, Debug, Default, Clone)]
106#[non_exhaustive]
107pub enum DeJsonTok {
108    Str,
109    Char(char),
110    U64(u64),
111    I64(i64),
112    F64(f64),
113    Bool(bool),
114    BareIdent,
115    Null,
116    Colon,
117    CurlyOpen,
118    CurlyClose,
119    BlockOpen,
120    BlockClose,
121    Comma,
122    #[default]
123    Bof,
124    Eof,
125}
126
127/// The internal state of a JSON deserialization.
128#[derive(Default)]
129#[non_exhaustive]
130pub struct DeJsonState {
131    pub cur: char,
132    pub tok: DeJsonTok,
133    pub strbuf: String,
134    pub numbuf: String,
135    pub identbuf: String,
136    pub line: usize,
137    pub col: usize,
138}
139
140#[derive(Clone)]
141#[non_exhaustive]
142pub enum DeJsonErrReason {
143    UnexpectedKey(String),
144    UnexpectedToken(DeJsonTok, String),
145    MissingKey(String),
146    NoSuchEnum(String),
147    OutOfRange(String),
148    WrongType(String),
149    CannotParse(String),
150}
151
152/// The error message when failing to deserialize a JSON string.
153#[derive(Clone)]
154pub struct DeJsonErr {
155    pub line: usize,
156    pub col: usize,
157    pub msg: DeJsonErrReason,
158}
159
160impl core::fmt::Debug for DeJsonErrReason {
161    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162        match self {
163            Self::UnexpectedKey(name) => write!(f, "Unexpected key {}", name),
164            Self::MissingKey(name) => write!(f, "Key not found {}", name),
165            Self::NoSuchEnum(name) => write!(f, "Enum not defined {}", name),
166            Self::UnexpectedToken(token, name) => {
167                write!(f, "Unexpected token {:?} expected {} ", token, name)
168            }
169            Self::OutOfRange(value) => write!(f, "Value out of range {} ", value),
170            Self::WrongType(found) => write!(f, "Token wrong type {} ", found),
171            Self::CannotParse(unparseable) => write!(f, "Cannot parse {} ", unparseable),
172        }
173    }
174}
175
176impl core::fmt::Debug for DeJsonErr {
177    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
178        let DeJsonErr {
179            line,
180            col: column,
181            msg: reason,
182        } = self;
183        write!(
184            f,
185            "Json Deserialize error: {:?}, line:{} col:{}",
186            reason,
187            line + 1,
188            column + 1
189        )
190    }
191}
192
193impl core::fmt::Display for DeJsonErr {
194    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
195        core::fmt::Debug::fmt(self, f)
196    }
197}
198
199impl Error for DeJsonErr {}
200
201impl DeJsonState {
202    pub fn next(&mut self, i: &mut Chars) {
203        if let Some(c) = i.next() {
204            self.cur = c;
205            if self.cur == '\n' {
206                self.line += 1;
207                self.col = 0;
208            } else {
209                self.col += 1;
210            }
211        } else {
212            self.cur = '\0';
213        }
214    }
215
216    pub fn err_exp(&self, name: &str) -> DeJsonErr {
217        DeJsonErr {
218            msg: DeJsonErrReason::UnexpectedKey(name.to_string()),
219            line: self.line,
220            col: self.col,
221        }
222    }
223
224    pub fn err_nf(&self, name: &str) -> DeJsonErr {
225        DeJsonErr {
226            msg: DeJsonErrReason::MissingKey(name.to_string()),
227            line: self.line,
228            col: self.col,
229        }
230    }
231
232    pub fn err_enum(&self, name: &str) -> DeJsonErr {
233        DeJsonErr {
234            msg: DeJsonErrReason::NoSuchEnum(name.to_string()),
235            line: self.line,
236            col: self.col,
237        }
238    }
239
240    pub fn err_token(&self, what: &str) -> DeJsonErr {
241        DeJsonErr {
242            msg: DeJsonErrReason::UnexpectedToken(self.tok.clone(), what.to_string()),
243            line: self.line,
244            col: self.col,
245        }
246    }
247
248    pub fn err_range(&self, what: &str) -> DeJsonErr {
249        DeJsonErr {
250            msg: DeJsonErrReason::OutOfRange(what.to_string()),
251            line: self.line,
252            col: self.col,
253        }
254    }
255
256    pub fn err_type(&self, what: &str) -> DeJsonErr {
257        DeJsonErr {
258            msg: DeJsonErrReason::WrongType(what.to_string()),
259            line: self.line,
260            col: self.col,
261        }
262    }
263
264    pub fn err_parse(&self, what: &str) -> DeJsonErr {
265        DeJsonErr {
266            msg: DeJsonErrReason::CannotParse(what.to_string()),
267            line: self.line,
268            col: self.col,
269        }
270    }
271
272    pub fn eat_comma_block(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
273        match self.tok {
274            DeJsonTok::Comma => {
275                self.next_tok(i)?;
276                Ok(())
277            }
278            DeJsonTok::BlockClose => Ok(()),
279            _ => Err(self.err_token(", or ]")),
280        }
281    }
282
283    pub fn whole_field(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
284        match self.tok {
285            DeJsonTok::F64 { .. }
286            | DeJsonTok::I64 { .. }
287            | DeJsonTok::Str
288            | DeJsonTok::U64 { .. }
289            | DeJsonTok::Bool { .. }
290            | DeJsonTok::Null => {
291                self.next_tok(i)?;
292                Ok(())
293            }
294            DeJsonTok::BlockOpen | DeJsonTok::CurlyOpen => {
295                let mut open_brackets = 0;
296
297                loop {
298                    if let DeJsonTok::BlockOpen | DeJsonTok::CurlyOpen = self.tok {
299                        open_brackets += 1;
300                    }
301
302                    if let DeJsonTok::BlockClose | DeJsonTok::CurlyClose = self.tok {
303                        open_brackets -= 1;
304                    }
305
306                    self.next_tok(i)?;
307
308                    if open_brackets == 0 {
309                        break;
310                    }
311                }
312                Ok(())
313            }
314            _ => unimplemented!("{:?}", self.tok),
315        }
316    }
317
318    pub fn eat_comma_curly(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
319        match self.tok {
320            DeJsonTok::Comma => {
321                self.next_tok(i)?;
322                Ok(())
323            }
324            DeJsonTok::CurlyClose => Ok(()),
325            _ => Err(self.err_token(", or }")),
326        }
327    }
328
329    pub fn colon(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
330        match self.tok {
331            DeJsonTok::Colon => {
332                self.next_tok(i)?;
333                Ok(())
334            }
335            _ => Err(self.err_token(":")),
336        }
337    }
338
339    pub fn string(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
340        match &mut self.tok {
341            DeJsonTok::Str => {
342                self.next_tok(i)?;
343                Ok(())
344            }
345            _ => Err(self.err_token("String")),
346        }
347    }
348
349    pub fn next_colon(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
350        self.next_tok(i)?;
351        self.colon(i)?;
352        Ok(())
353    }
354
355    pub fn next_str(&mut self) -> Option<()> {
356        if let DeJsonTok::Str = &mut self.tok {
357            //let mut s = String::new();
358            //core::mem::swap(&mut s, name);
359            Some(())
360        } else {
361            None
362        }
363    }
364
365    pub fn block_open(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
366        if self.tok == DeJsonTok::BlockOpen {
367            self.next_tok(i)?;
368            return Ok(());
369        }
370        Err(self.err_token("["))
371    }
372
373    pub fn block_close(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
374        if self.tok == DeJsonTok::BlockClose {
375            self.next_tok(i)?;
376            return Ok(());
377        }
378        Err(self.err_token("]"))
379    }
380
381    pub fn curly_open(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
382        if self.tok == DeJsonTok::CurlyOpen {
383            self.next_tok(i)?;
384            return Ok(());
385        }
386        Err(self.err_token("{"))
387    }
388
389    pub fn curly_close(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
390        if self.tok == DeJsonTok::CurlyClose {
391            self.next_tok(i)?;
392            return Ok(());
393        }
394        Err(self.err_token("}"))
395    }
396
397    pub fn u64_range(&mut self, max: u64) -> Result<u64, DeJsonErr> {
398        if let DeJsonTok::U64(value) = self.tok {
399            if value > max {
400                return Err(self.err_range(&format!("{}>{}", value, max)));
401            }
402            return Ok(value);
403        }
404        Err(self.err_token("unsigned integer"))
405    }
406
407    pub fn i64_range(&mut self, min: i64, max: i64) -> Result<i64, DeJsonErr> {
408        if let DeJsonTok::I64(value) = self.tok {
409            if value < min {
410                return Err(self.err_range(&format!("{}<{}", value, min)));
411            }
412            return Ok(value);
413        }
414        if let DeJsonTok::U64(value) = self.tok {
415            if value as i64 > max {
416                return Err(self.err_range(&format!("{}>{}", value, max)));
417            }
418            return Ok(value as i64);
419        }
420        Err(self.err_token("signed integer"))
421    }
422
423    pub fn as_f64(&mut self) -> Result<f64, DeJsonErr> {
424        if let DeJsonTok::I64(value) = self.tok {
425            return Ok(value as f64);
426        }
427        if let DeJsonTok::U64(value) = self.tok {
428            return Ok(value as f64);
429        }
430        if let DeJsonTok::F64(value) = self.tok {
431            return Ok(value);
432        }
433        Err(self.err_token("floating point"))
434    }
435
436    pub fn as_bool(&mut self) -> Result<bool, DeJsonErr> {
437        if let DeJsonTok::Bool(value) = self.tok {
438            return Ok(value);
439        }
440        Err(self.err_token("boolean"))
441    }
442
443    pub fn as_string(&mut self) -> Result<String, DeJsonErr> {
444        if let DeJsonTok::Str = &mut self.tok {
445            let mut val = String::new();
446            core::mem::swap(&mut val, &mut self.strbuf);
447            return Ok(val);
448        }
449        Err(self.err_token("string"))
450    }
451
452    pub fn next_tok(&mut self, i: &mut Chars) -> Result<(), DeJsonErr> {
453        while self.cur == '\n' || self.cur == '\r' || self.cur == '\t' || self.cur == ' ' {
454            self.next(i);
455        }
456        if self.cur == '\0' {
457            self.tok = DeJsonTok::Eof;
458            return Ok(());
459        }
460        if self.cur == '/' {
461            self.next(i);
462            match self.cur {
463                '/' => {
464                    while self.cur != '\n' && self.cur != '\0' {
465                        self.next(i);
466                    }
467                    return self.next_tok(i);
468                }
469                '*' => {
470                    let mut last = self.cur;
471                    loop {
472                        self.next(i);
473                        if self.cur == '\0' {
474                            return Err(self.err_token("MultiLineCommentClose"));
475                        }
476                        if last == '*' && self.cur == '/' {
477                            self.next(i);
478                            break;
479                        }
480                        last = self.cur;
481                    }
482                    return self.next_tok(i);
483                }
484                _ => {
485                    return Err(self.err_token("CommentOpen"));
486                }
487            }
488        }
489        match self.cur {
490            ':' => {
491                self.next(i);
492                self.tok = DeJsonTok::Colon;
493                Ok(())
494            }
495            ',' => {
496                self.next(i);
497                self.tok = DeJsonTok::Comma;
498                Ok(())
499            }
500            '[' => {
501                self.next(i);
502                self.tok = DeJsonTok::BlockOpen;
503                Ok(())
504            }
505            ']' => {
506                self.next(i);
507                self.tok = DeJsonTok::BlockClose;
508                Ok(())
509            }
510            '{' => {
511                self.next(i);
512                self.tok = DeJsonTok::CurlyOpen;
513                Ok(())
514            }
515            '}' => {
516                self.next(i);
517                self.tok = DeJsonTok::CurlyClose;
518                Ok(())
519            }
520            '-' | '+' | '0'..='9' => {
521                self.numbuf.truncate(0);
522                let is_neg = if self.cur == '-' || self.cur == '+' {
523                    let sign = self.cur;
524                    self.numbuf.push(self.cur);
525                    self.next(i);
526                    sign == '-'
527                } else {
528                    false
529                };
530                while self.cur >= '0' && self.cur <= '9' {
531                    self.numbuf.push(self.cur);
532                    self.next(i);
533                }
534                let mut is_float = false;
535                if self.cur == '.' {
536                    is_float = true;
537                    self.numbuf.push(self.cur);
538                    self.next(i);
539                    while self.cur >= '0' && self.cur <= '9' {
540                        self.numbuf.push(self.cur);
541                        self.next(i);
542                    }
543                }
544                if self.cur == 'e' || self.cur == 'E' {
545                    is_float = true;
546                    self.numbuf.push(self.cur);
547                    self.next(i);
548                    if self.cur == '-' {
549                        self.numbuf.push(self.cur);
550                        self.next(i);
551                    }
552                    while self.cur >= '0' && self.cur <= '9' {
553                        self.numbuf.push(self.cur);
554                        self.next(i);
555                    }
556                }
557                if is_float {
558                    if let Ok(num) = self.numbuf.parse() {
559                        self.tok = DeJsonTok::F64(num);
560                        Ok(())
561                    } else {
562                        Err(self.err_parse("number"))
563                    }
564                } else {
565                    if is_neg {
566                        if let Ok(num) = self.numbuf.parse() {
567                            self.tok = DeJsonTok::I64(num);
568                            return Ok(());
569                        } else {
570                            return Err(self.err_parse("number"));
571                        }
572                    }
573                    if let Ok(num) = self.numbuf.parse() {
574                        self.tok = DeJsonTok::U64(num);
575                        Ok(())
576                    } else {
577                        Err(self.err_parse("number"))
578                    }
579                }
580            }
581            'a'..='z' | 'A'..='Z' | '_' => {
582                self.identbuf.truncate(0);
583                while self.cur >= 'a' && self.cur <= 'z'
584                    || self.cur >= 'A' && self.cur <= 'Z'
585                    || self.cur == '_'
586                {
587                    self.identbuf.push(self.cur);
588                    self.next(i);
589                }
590                if self.identbuf == "true" {
591                    self.tok = DeJsonTok::Bool(true);
592                    return Ok(());
593                }
594                if self.identbuf == "false" {
595                    self.tok = DeJsonTok::Bool(false);
596                    return Ok(());
597                }
598                if self.identbuf == "null" {
599                    self.tok = DeJsonTok::Null;
600                    return Ok(());
601                }
602                self.tok = DeJsonTok::BareIdent;
603                Err(self.err_token(&format!(
604                    "Got ##{}## needed true, false, null",
605                    self.identbuf
606                )))
607            }
608            '"' => {
609                self.strbuf.truncate(0);
610                self.next(i);
611                while self.cur != '"' {
612                    if self.cur == '\\' {
613                        self.next(i);
614                        match self.cur {
615                            'n' => self.strbuf.push('\n'),
616                            'r' => self.strbuf.push('\r'),
617                            't' => self.strbuf.push('\t'),
618                            'b' => self.strbuf.push('\x08'),
619                            'f' => self.strbuf.push('\x0c'),
620                            '0' => self.strbuf.push('\0'),
621                            '\0' => {
622                                return Err(self.err_parse("string"));
623                            }
624                            'u' => {
625                                if let Some(c) = self.hex_unescape_char(i) {
626                                    self.strbuf.push(c);
627                                    continue;
628                                } else {
629                                    return Err(self.err_parse("string"));
630                                }
631                            }
632                            _ => self.strbuf.push(self.cur),
633                        }
634                        self.next(i);
635                    } else {
636                        if self.cur == '\0' {
637                            return Err(self.err_parse("string"));
638                        }
639                        self.strbuf.push(self.cur);
640                        self.next(i);
641                    }
642                }
643                self.next(i);
644                self.tok = DeJsonTok::Str;
645                Ok(())
646            }
647            _ => Err(self.err_token("tokenizer")),
648        }
649    }
650
651    /// Helper for reading `\uXXXX` escapes out of a string, properly handing
652    /// surrogate pairs (by potentially unescaping a second `\uXXXX` sequence if
653    /// it would complete a surrogate pair).
654    ///
655    /// On illegal escapes or unpaired surrogates returns None (and caller
656    /// should emit an error).
657    fn hex_unescape_char(&mut self, i: &mut Chars) -> Option<char> {
658        self.next(i);
659        let a = xdigit4(self, i)?;
660        if let Some(c) = core::char::from_u32(a as u32) {
661            return Some(c);
662        }
663        // `a` isn't a valid scalar, but if it's leading surrogate, we look for
664        // a trailing surrogate in a `\uXXXX` sequence immediately after.
665        let a_is_lead = (0xd800..0xdc00).contains(&a);
666        if a_is_lead && self.cur == '\\' {
667            self.next(i);
668            if self.cur == 'u' {
669                self.next(i);
670                let b = xdigit4(self, i)?;
671                let b_is_trail = (0xdc00..0xe000).contains(&b);
672                if b_is_trail {
673                    // It's a valid pair! We have `[a, b]` where `a` is a leading
674                    // surrogate and `b` is a trailing one.
675                    let scalar = (((a as u32 - 0xd800) << 10) | (b as u32 - 0xdc00)) + 0x10000;
676                    // All valid surrogate pairs decode to unicode scalar values
677                    // (e.g. `char`), so this block should always return `Some`, the
678                    // debug_assert exists just to ensure our testing is thorough
679                    // enough.
680                    let ch = core::char::from_u32(scalar);
681                    debug_assert!(ch.is_some());
682                    return ch;
683                }
684            }
685        }
686        return None;
687
688        // Helper to turn next 4 ascii hex digits into a u16
689        fn xdigit4(de: &mut DeJsonState, i: &mut Chars) -> Option<u16> {
690            // as tempting as it is to try to find a way to use from_str_radix on the
691            // next 4 bytes from `i`, we'd still need to do validation to detect cases
692            // like `\u+123` and such which makes it less attractive.
693            (0..4).try_fold(0u16, |acc, _| {
694                let n = match de.cur {
695                    '0'..='9' => de.cur as u16 - '0' as u16,
696                    'a'..='f' => de.cur as u16 - 'a' as u16 + 10,
697                    'A'..='F' => de.cur as u16 - 'A' as u16 + 10,
698                    _ => return None,
699                };
700                de.next(i);
701                Some(acc * 16 + n)
702            })
703        }
704    }
705}
706
707macro_rules! impl_ser_de_json_unsigned {
708    ( $ ty: ident, $ max: expr) => {
709        impl SerJson for $ty {
710            fn ser_json(&self, _d: usize, s: &mut SerJsonState) {
711                s.out.push_str(&self.to_string());
712            }
713        }
714
715        impl DeJson for $ty {
716            fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<$ty, DeJsonErr> {
717                let val = s.u64_range($max as u64)?;
718                s.next_tok(i)?;
719                return Ok(val as $ty);
720            }
721        }
722    };
723}
724
725macro_rules! impl_ser_de_json_signed {
726    ( $ ty: ident, $ min: expr, $ max: expr) => {
727        impl SerJson for $ty {
728            fn ser_json(&self, _d: usize, s: &mut SerJsonState) {
729                s.out.push_str(&self.to_string());
730            }
731        }
732
733        impl DeJson for $ty {
734            fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<$ty, DeJsonErr> {
735                //s.is_prefix(p, i) ?;
736                let val = s.i64_range($min as i64, $max as i64)?;
737                s.next_tok(i)?;
738                return Ok(val as $ty);
739            }
740        }
741    };
742}
743
744macro_rules! impl_ser_de_json_float {
745    ( $ ty: ident) => {
746        impl SerJson for $ty {
747            fn ser_json(&self, _d: usize, s: &mut SerJsonState) {
748                s.out.push_str(&format!("{self:?}"));
749            }
750        }
751
752        impl DeJson for $ty {
753            fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<$ty, DeJsonErr> {
754                //s.is_prefix(p, i) ?;
755                let val = s.as_f64()?;
756                s.next_tok(i)?;
757                return Ok(val as $ty);
758            }
759        }
760    };
761}
762
763impl_ser_de_json_unsigned!(usize, u64::MAX);
764impl_ser_de_json_unsigned!(u64, u64::MAX);
765impl_ser_de_json_unsigned!(u32, u32::MAX);
766impl_ser_de_json_unsigned!(u16, u16::MAX);
767impl_ser_de_json_unsigned!(u8, u8::MAX);
768impl_ser_de_json_signed!(i64, i64::MIN, i64::MAX);
769impl_ser_de_json_signed!(i32, i32::MIN, i32::MAX);
770impl_ser_de_json_signed!(i16, i16::MIN, i16::MAX);
771impl_ser_de_json_signed!(i8, i8::MIN, i8::MAX);
772impl_ser_de_json_float!(f64);
773impl_ser_de_json_float!(f32);
774
775impl<T> SerJson for Option<T>
776where
777    T: SerJson,
778{
779    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
780        if let Some(v) = self {
781            v.ser_json(d, s);
782        } else {
783            s.out.push_str("null");
784        }
785    }
786}
787
788impl<T> DeJson for Option<T>
789where
790    T: DeJson,
791{
792    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<Self, DeJsonErr> {
793        if let DeJsonTok::Null = s.tok {
794            s.next_tok(i)?;
795            return Ok(None);
796        }
797        Ok(Some(DeJson::de_json(s, i)?))
798    }
799}
800
801impl SerJson for () {
802    fn ser_json(&self, _d: usize, s: &mut SerJsonState) {
803        s.out.push_str("null")
804    }
805}
806
807impl DeJson for () {
808    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<(), DeJsonErr> {
809        if let DeJsonTok::Null = s.tok {
810            s.next_tok(i)?;
811            Ok(())
812        } else {
813            Err(s.err_token("null"))
814        }
815    }
816}
817
818impl SerJson for bool {
819    fn ser_json(&self, _d: usize, s: &mut SerJsonState) {
820        if *self {
821            s.out.push_str("true")
822        } else {
823            s.out.push_str("false")
824        }
825    }
826}
827
828impl DeJson for bool {
829    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<bool, DeJsonErr> {
830        let val = s.as_bool()?;
831        s.next_tok(i)?;
832        Ok(val)
833    }
834}
835
836macro_rules! impl_ser_json_string {
837    ($ty: ident) => {
838        impl SerJson for $ty {
839            fn ser_json(&self, _d: usize, s: &mut SerJsonState) {
840                s.out.push('"');
841                for c in self.chars() {
842                    match c {
843                        '\x08' => s.out += "\\b",
844                        '\x0C' => s.out += "\\f",
845                        '\n' => s.out += "\\n",
846                        '\r' => s.out += "\\r",
847                        '\t' => s.out += "\\t",
848                        _ if c.is_ascii_control() => {
849                            use core::fmt::Write as _;
850                            let _ = write!(s.out, "\\u{:04x}", c as u32);
851                        }
852                        '\\' => s.out += "\\\\",
853                        '"' => s.out += "\\\"",
854                        _ => s.out.push(c),
855                    }
856                }
857                s.out.push('"');
858            }
859        }
860    };
861}
862
863impl_ser_json_string!(String);
864impl_ser_json_string!(str);
865
866impl DeJson for String {
867    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<String, DeJsonErr> {
868        let val = s.as_string()?;
869        s.next_tok(i)?;
870        Ok(val)
871    }
872}
873
874impl<T> SerJson for Vec<T>
875where
876    T: SerJson,
877{
878    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
879        s.out.push('[');
880        if !self.is_empty() {
881            let last = self.len() - 1;
882            for (index, item) in self.iter().enumerate() {
883                s.indent(d + 1);
884                item.ser_json(d + 1, s);
885                if index != last {
886                    s.out.push(',');
887                }
888            }
889        }
890        s.out.push(']');
891    }
892}
893
894impl<T> DeJson for Vec<T>
895where
896    T: DeJson,
897{
898    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<Vec<T>, DeJsonErr> {
899        let mut out = Vec::new();
900        s.block_open(i)?;
901
902        while s.tok != DeJsonTok::BlockClose {
903            out.push(DeJson::de_json(s, i)?);
904            s.eat_comma_block(i)?;
905        }
906        s.block_close(i)?;
907        Ok(out)
908    }
909}
910
911#[cfg(feature = "std")]
912impl<T> SerJson for std::collections::HashSet<T>
913where
914    T: SerJson,
915{
916    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
917        s.out.push('[');
918        if !self.is_empty() {
919            let last = self.len() - 1;
920            for (index, item) in self.iter().enumerate() {
921                s.indent(d + 1);
922                item.ser_json(d + 1, s);
923                if index != last {
924                    s.out.push(',');
925                }
926            }
927        }
928        s.out.push(']');
929    }
930}
931
932#[cfg(feature = "std")]
933impl<T> DeJson for std::collections::HashSet<T>
934where
935    T: DeJson + core::hash::Hash + Eq,
936{
937    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<Self, DeJsonErr> {
938        let mut out = std::collections::HashSet::new();
939        s.block_open(i)?;
940
941        while s.tok != DeJsonTok::BlockClose {
942            out.insert(DeJson::de_json(s, i)?);
943            s.eat_comma_block(i)?;
944        }
945        s.block_close(i)?;
946        Ok(out)
947    }
948}
949
950impl<T> SerJson for LinkedList<T>
951where
952    T: SerJson,
953{
954    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
955        s.out.push('[');
956        if !self.is_empty() {
957            let last = self.len() - 1;
958            for (index, item) in self.iter().enumerate() {
959                s.indent(d + 1);
960                item.ser_json(d + 1, s);
961                if index != last {
962                    s.out.push(',');
963                }
964            }
965        }
966        s.out.push(']');
967    }
968}
969
970impl<T> DeJson for LinkedList<T>
971where
972    T: DeJson,
973{
974    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<LinkedList<T>, DeJsonErr> {
975        let mut out = LinkedList::new();
976        s.block_open(i)?;
977
978        while s.tok != DeJsonTok::BlockClose {
979            out.push_back(DeJson::de_json(s, i)?);
980            s.eat_comma_block(i)?;
981        }
982        s.block_close(i)?;
983        Ok(out)
984    }
985}
986
987impl<T> SerJson for BTreeSet<T>
988where
989    T: SerJson,
990{
991    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
992        s.out.push('[');
993        if !self.is_empty() {
994            let last = self.len() - 1;
995            for (index, item) in self.iter().enumerate() {
996                s.indent(d + 1);
997                item.ser_json(d + 1, s);
998                if index != last {
999                    s.out.push(',');
1000                }
1001            }
1002        }
1003        s.out.push(']');
1004    }
1005}
1006
1007impl<T> DeJson for BTreeSet<T>
1008where
1009    T: DeJson + Ord,
1010{
1011    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<BTreeSet<T>, DeJsonErr> {
1012        let mut out = BTreeSet::new();
1013        s.block_open(i)?;
1014
1015        while s.tok != DeJsonTok::BlockClose {
1016            out.insert(DeJson::de_json(s, i)?);
1017            s.eat_comma_block(i)?;
1018        }
1019        s.block_close(i)?;
1020        Ok(out)
1021    }
1022}
1023
1024impl<T> SerJson for [T]
1025where
1026    T: SerJson,
1027{
1028    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1029        s.out.push('[');
1030        let last = self.len() - 1;
1031        for (index, item) in self.iter().enumerate() {
1032            item.ser_json(d + 1, s);
1033            if index != last {
1034                s.out.push(',');
1035            }
1036        }
1037        s.out.push(']');
1038    }
1039}
1040
1041impl<T, const N: usize> SerJson for [T; N]
1042where
1043    T: SerJson,
1044{
1045    #[inline(always)]
1046    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1047        self.as_slice().ser_json(d, s)
1048    }
1049}
1050
1051impl<T, const N: usize> DeJson for [T; N]
1052where
1053    T: DeJson,
1054{
1055    fn de_json(o: &mut DeJsonState, d: &mut Chars) -> Result<Self, DeJsonErr> {
1056        use core::mem::MaybeUninit;
1057
1058        // waiting for uninit_array(or for array::try_from_fn) stabilization
1059        // https://github.com/rust-lang/rust/issues/96097
1060        // https://github.com/rust-lang/rust/issues/89379
1061        let mut to: [MaybeUninit<T>; N] =
1062            unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() };
1063        o.block_open(d)?;
1064
1065        for index in 0..N {
1066            to[index] = match DeJson::de_json(o, d).and_then(|ret| {
1067                o.eat_comma_block(d)?;
1068                Ok(ret)
1069            }) {
1070                Ok(v) => MaybeUninit::new(v),
1071                Err(e) => {
1072                    // drop all the MaybeUninit values which we've already
1073                    // successfully deserialized so we don't leak memory.
1074                    // See https://github.com/not-fl3/nanoserde/issues/79
1075                    for (_, to_drop) in (0..index).zip(to) {
1076                        unsafe { to_drop.assume_init() };
1077                    }
1078                    return Err(e);
1079                }
1080            }
1081        }
1082
1083        // waiting for array_assume_init or core::array::map optimizations
1084        // https://github.com/rust-lang/rust/issues/61956
1085        // initializing before block close so that drop will run automatically if err encountered there
1086        let initialized =
1087            unsafe { (*(&to as *const _ as *const MaybeUninit<_>)).assume_init_read() };
1088        o.block_close(d)?;
1089
1090        Ok(initialized)
1091    }
1092}
1093
1094fn de_json_comma_block<T>(s: &mut DeJsonState, i: &mut Chars) -> Result<T, DeJsonErr>
1095where
1096    T: DeJson,
1097{
1098    let t = DeJson::de_json(s, i);
1099    s.eat_comma_block(i)?;
1100    t
1101}
1102
1103impl<A, B> SerJson for (A, B)
1104where
1105    A: SerJson,
1106    B: SerJson,
1107{
1108    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1109        s.out.push('[');
1110        self.0.ser_json(d, s);
1111        s.out.push(',');
1112        self.1.ser_json(d, s);
1113        s.out.push(']');
1114    }
1115}
1116
1117impl<A, B> DeJson for (A, B)
1118where
1119    A: DeJson,
1120    B: DeJson,
1121{
1122    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<(A, B), DeJsonErr> {
1123        s.block_open(i)?;
1124        let r = (de_json_comma_block(s, i)?, de_json_comma_block(s, i)?);
1125        s.block_close(i)?;
1126        Ok(r)
1127    }
1128}
1129
1130impl<A, B, C> SerJson for (A, B, C)
1131where
1132    A: SerJson,
1133    B: SerJson,
1134    C: SerJson,
1135{
1136    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1137        s.out.push('[');
1138        self.0.ser_json(d, s);
1139        s.out.push(',');
1140        self.1.ser_json(d, s);
1141        s.out.push(',');
1142        self.2.ser_json(d, s);
1143        s.out.push(']');
1144    }
1145}
1146
1147impl<A, B, C> DeJson for (A, B, C)
1148where
1149    A: DeJson,
1150    B: DeJson,
1151    C: DeJson,
1152{
1153    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<(A, B, C), DeJsonErr> {
1154        s.block_open(i)?;
1155        let r = (
1156            de_json_comma_block(s, i)?,
1157            de_json_comma_block(s, i)?,
1158            de_json_comma_block(s, i)?,
1159        );
1160        s.block_close(i)?;
1161        Ok(r)
1162    }
1163}
1164
1165impl<A, B, C, D> SerJson for (A, B, C, D)
1166where
1167    A: SerJson,
1168    B: SerJson,
1169    C: SerJson,
1170    D: SerJson,
1171{
1172    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1173        s.out.push('[');
1174        self.0.ser_json(d, s);
1175        s.out.push(',');
1176        self.1.ser_json(d, s);
1177        s.out.push(',');
1178        self.2.ser_json(d, s);
1179        s.out.push(',');
1180        self.3.ser_json(d, s);
1181        s.out.push(']');
1182    }
1183}
1184
1185impl<A, B, C, D> DeJson for (A, B, C, D)
1186where
1187    A: DeJson,
1188    B: DeJson,
1189    C: DeJson,
1190    D: DeJson,
1191{
1192    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<(A, B, C, D), DeJsonErr> {
1193        s.block_open(i)?;
1194        let r = (
1195            de_json_comma_block(s, i)?,
1196            de_json_comma_block(s, i)?,
1197            de_json_comma_block(s, i)?,
1198            de_json_comma_block(s, i)?,
1199        );
1200        s.block_close(i)?;
1201        Ok(r)
1202    }
1203}
1204
1205#[cfg(feature = "std")]
1206impl<K, V> SerJson for std::collections::HashMap<K, V>
1207where
1208    K: SerJson,
1209    V: SerJson,
1210{
1211    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1212        s.out.push('{');
1213        let len = self.len();
1214        for (index, (k, v)) in self.iter().enumerate() {
1215            s.indent(d + 1);
1216            k.ser_json(d + 1, s);
1217            s.out.push(':');
1218            v.ser_json(d + 1, s);
1219            if (index + 1) < len {
1220                s.conl();
1221            }
1222        }
1223        s.indent(d);
1224        s.out.push('}');
1225    }
1226}
1227
1228#[cfg(feature = "std")]
1229impl<K, V> DeJson for std::collections::HashMap<K, V>
1230where
1231    K: DeJson + Eq + core::hash::Hash,
1232    V: DeJson,
1233{
1234    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<Self, DeJsonErr> {
1235        let mut h = std::collections::HashMap::new();
1236        s.curly_open(i)?;
1237        while s.tok != DeJsonTok::CurlyClose {
1238            let k = DeJson::de_json(s, i)?;
1239            s.colon(i)?;
1240            let v = DeJson::de_json(s, i)?;
1241            s.eat_comma_curly(i)?;
1242            h.insert(k, v);
1243        }
1244        s.curly_close(i)?;
1245        Ok(h)
1246    }
1247}
1248
1249impl<K, V> SerJson for BTreeMap<K, V>
1250where
1251    K: SerJson,
1252    V: SerJson,
1253{
1254    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1255        s.out.push('{');
1256        let len = self.len();
1257        for (index, (k, v)) in self.iter().enumerate() {
1258            s.indent(d + 1);
1259            k.ser_json(d + 1, s);
1260            s.out.push(':');
1261            v.ser_json(d + 1, s);
1262            if (index + 1) < len {
1263                s.conl();
1264            }
1265        }
1266        s.indent(d);
1267        s.out.push('}');
1268    }
1269}
1270
1271impl<K, V> DeJson for BTreeMap<K, V>
1272where
1273    K: DeJson + Eq + Ord,
1274    V: DeJson,
1275{
1276    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<Self, DeJsonErr> {
1277        let mut h = BTreeMap::new();
1278        s.curly_open(i)?;
1279        while s.tok != DeJsonTok::CurlyClose {
1280            let k = DeJson::de_json(s, i)?;
1281            s.colon(i)?;
1282            let v = DeJson::de_json(s, i)?;
1283            s.eat_comma_curly(i)?;
1284            h.insert(k, v);
1285        }
1286        s.curly_close(i)?;
1287        Ok(h)
1288    }
1289}
1290
1291impl<T> SerJson for Box<T>
1292where
1293    T: SerJson,
1294{
1295    fn ser_json(&self, d: usize, s: &mut SerJsonState) {
1296        (**self).ser_json(d, s)
1297    }
1298}
1299
1300impl<T> DeJson for Box<T>
1301where
1302    T: DeJson,
1303{
1304    fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result<Box<T>, DeJsonErr> {
1305        Ok(Box::new(DeJson::de_json(s, i)?))
1306    }
1307}