Skip to main content

fixed_json/
lib.rs

1#![no_std]
2
3#[cfg(feature = "std")]
4extern crate std;
5
6pub const JSON_ATTR_MAX: usize = 31;
7pub const JSON_VAL_MAX: usize = 512;
8
9pub type Result<T> = core::result::Result<T, Error>;
10
11#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12#[repr(i32)]
13pub enum Error {
14    ObStart = 1,
15    AttrStart = 2,
16    BadAttr = 3,
17    AttrLen = 4,
18    NoArray = 5,
19    NoBrak = 6,
20    StrLong = 7,
21    TokLong = 8,
22    BadTrail = 9,
23    ArrayStart = 10,
24    ObjArr = 11,
25    SubTooLong = 12,
26    BadSubTrail = 13,
27    SubType = 14,
28    BadString = 15,
29    CheckFail = 16,
30    NoParStr = 17,
31    BadEnum = 18,
32    QNonString = 19,
33    NonQString = 20,
34    Misc = 21,
35    BadNum = 22,
36    NullPtr = 23,
37    NoCurly = 24,
38    Empty = 25,
39}
40
41impl Error {
42    pub const fn message(self) -> &'static str {
43        match self {
44            Error::ObStart => "non-whitespace when expecting object start",
45            Error::AttrStart => "non-whitespace when expecting attribute start",
46            Error::BadAttr => "unknown attribute name",
47            Error::AttrLen => "attribute name too long",
48            Error::NoArray => "saw [ when not expecting array",
49            Error::NoBrak => "array element specified, but no [",
50            Error::StrLong => "string value too long",
51            Error::TokLong => "token value too long",
52            Error::BadTrail => "garbage while expecting comma or } or ]",
53            Error::ArrayStart => "didn't find expected array start",
54            Error::ObjArr => "error while parsing object array",
55            Error::SubTooLong => "too many array elements",
56            Error::BadSubTrail => "garbage while expecting array comma",
57            Error::SubType => "unsupported array element type",
58            Error::BadString => "error while string parsing",
59            Error::CheckFail => "check attribute not matched",
60            Error::NoParStr => "can't support strings in parallel arrays",
61            Error::BadEnum => "invalid enumerated value",
62            Error::QNonString => "saw quoted value when expecting nonstring",
63            Error::NonQString => "didn't see quoted value when expecting string",
64            Error::Misc => "other data conversion error",
65            Error::BadNum => "error while parsing a numerical argument",
66            Error::NullPtr => "unexpected null value or attribute pointer",
67            Error::NoCurly => "object element specified, but no {",
68            Error::Empty => "input was empty or white-space only",
69        }
70    }
71}
72
73impl core::fmt::Display for Error {
74    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
75        f.write_str(self.message())
76    }
77}
78
79#[cfg(feature = "std")]
80impl std::error::Error for Error {}
81
82pub fn error_string(err: Error) -> &'static str {
83    err.message()
84}
85
86#[derive(Clone, Copy)]
87pub struct EnumValue<'a> {
88    pub name: &'a str,
89    pub value: i32,
90}
91
92#[derive(Clone, Copy)]
93pub enum DefaultValue<'a> {
94    None,
95    Integer(i32),
96    UInteger(u32),
97    Short(i16),
98    UShort(u16),
99    Real(f64),
100    Boolean(bool),
101    Character(u8),
102    Check(&'a str),
103}
104
105pub enum Target<'a, T> {
106    One(&'a mut T),
107    Many(&'a mut [T]),
108}
109
110impl<T: Copy> Target<'_, T> {
111    fn set(&mut self, offset: usize, value: T) -> Result<()> {
112        match self {
113            Target::One(target) if offset == 0 => {
114                **target = value;
115                Ok(())
116            }
117            Target::Many(targets) => {
118                *targets.get_mut(offset).ok_or(Error::SubTooLong)? = value;
119                Ok(())
120            }
121            Target::One(_) => Ok(()),
122        }
123    }
124}
125
126pub type TargetI32<'a> = Target<'a, i32>;
127pub type TargetU32<'a> = Target<'a, u32>;
128pub type TargetI16<'a> = Target<'a, i16>;
129pub type TargetU16<'a> = Target<'a, u16>;
130pub type TargetF64<'a> = Target<'a, f64>;
131pub type TargetBool<'a> = Target<'a, bool>;
132pub type TargetChar<'a> = Target<'a, u8>;
133
134pub enum AttrKind<'a> {
135    Integer(TargetI32<'a>),
136    UInteger(TargetU32<'a>),
137    Real(TargetF64<'a>),
138    String(&'a mut [u8]),
139    Boolean(TargetBool<'a>),
140    Character(TargetChar<'a>),
141    Time(TargetF64<'a>),
142    Object(&'a mut [Attr<'a>]),
143    Array(Array<'a>),
144    Check(&'a str),
145    Ignore,
146    Short(TargetI16<'a>),
147    UShort(TargetU16<'a>),
148}
149
150pub struct Attr<'a> {
151    pub name: &'a str,
152    pub kind: AttrKind<'a>,
153    pub default: DefaultValue<'a>,
154    pub map: Option<&'a [EnumValue<'a>]>,
155    pub nodefault: bool,
156}
157
158impl<'a> Attr<'a> {
159    pub fn integer(name: &'a str, target: &'a mut i32) -> Self {
160        Self::new(name, AttrKind::Integer(TargetI32::One(target)))
161    }
162
163    pub fn integers(name: &'a str, target: &'a mut [i32]) -> Self {
164        Self::new(name, AttrKind::Integer(TargetI32::Many(target)))
165    }
166
167    pub fn uinteger(name: &'a str, target: &'a mut u32) -> Self {
168        Self::new(name, AttrKind::UInteger(TargetU32::One(target)))
169    }
170
171    pub fn uintegers(name: &'a str, target: &'a mut [u32]) -> Self {
172        Self::new(name, AttrKind::UInteger(TargetU32::Many(target)))
173    }
174
175    pub fn short(name: &'a str, target: &'a mut i16) -> Self {
176        Self::new(name, AttrKind::Short(TargetI16::One(target)))
177    }
178
179    pub fn shorts(name: &'a str, target: &'a mut [i16]) -> Self {
180        Self::new(name, AttrKind::Short(TargetI16::Many(target)))
181    }
182
183    pub fn ushort(name: &'a str, target: &'a mut u16) -> Self {
184        Self::new(name, AttrKind::UShort(TargetU16::One(target)))
185    }
186
187    pub fn ushorts(name: &'a str, target: &'a mut [u16]) -> Self {
188        Self::new(name, AttrKind::UShort(TargetU16::Many(target)))
189    }
190
191    pub fn real(name: &'a str, target: &'a mut f64) -> Self {
192        Self::new(name, AttrKind::Real(TargetF64::One(target)))
193    }
194
195    pub fn reals(name: &'a str, target: &'a mut [f64]) -> Self {
196        Self::new(name, AttrKind::Real(TargetF64::Many(target)))
197    }
198
199    pub fn string(name: &'a str, target: &'a mut [u8]) -> Self {
200        Self::new(name, AttrKind::String(target))
201    }
202
203    pub fn boolean(name: &'a str, target: &'a mut bool) -> Self {
204        Self::new(name, AttrKind::Boolean(TargetBool::One(target)))
205    }
206
207    pub fn booleans(name: &'a str, target: &'a mut [bool]) -> Self {
208        Self::new(name, AttrKind::Boolean(TargetBool::Many(target)))
209    }
210
211    pub fn character(name: &'a str, target: &'a mut u8) -> Self {
212        Self::new(name, AttrKind::Character(TargetChar::One(target)))
213    }
214
215    pub fn characters(name: &'a str, target: &'a mut [u8]) -> Self {
216        Self::new(name, AttrKind::Character(TargetChar::Many(target)))
217    }
218
219    pub fn time(name: &'a str, target: &'a mut f64) -> Self {
220        Self::new(name, AttrKind::Time(TargetF64::One(target)))
221    }
222
223    pub fn object(name: &'a str, attrs: &'a mut [Attr<'a>]) -> Self {
224        Self::new(name, AttrKind::Object(attrs))
225    }
226
227    pub fn array(name: &'a str, array: Array<'a>) -> Self {
228        Self::new(name, AttrKind::Array(array))
229    }
230
231    pub fn check(name: &'a str, expected: &'a str) -> Self {
232        let mut attr = Self::new(name, AttrKind::Check(expected));
233        attr.default = DefaultValue::Check(expected);
234        attr
235    }
236
237    pub fn ignore_any() -> Self {
238        Self::new("", AttrKind::Ignore)
239    }
240
241    pub fn with_default(mut self, default: DefaultValue<'a>) -> Self {
242        self.default = default;
243        self
244    }
245
246    pub fn with_map(mut self, map: &'a [EnumValue<'a>]) -> Self {
247        self.map = Some(map);
248        self
249    }
250
251    pub fn nodefault(mut self) -> Self {
252        self.nodefault = true;
253        self
254    }
255
256    fn new(name: &'a str, kind: AttrKind<'a>) -> Self {
257        Self {
258            name,
259            kind,
260            default: DefaultValue::None,
261            map: None,
262            nodefault: false,
263        }
264    }
265}
266
267pub enum Array<'a> {
268    Strings {
269        store: &'a mut [&'a mut [u8]],
270        count: Option<&'a mut usize>,
271    },
272    Integers {
273        store: &'a mut [i32],
274        count: Option<&'a mut usize>,
275    },
276    UIntegers {
277        store: &'a mut [u32],
278        count: Option<&'a mut usize>,
279    },
280    Shorts {
281        store: &'a mut [i16],
282        count: Option<&'a mut usize>,
283    },
284    UShorts {
285        store: &'a mut [u16],
286        count: Option<&'a mut usize>,
287    },
288    Reals {
289        store: &'a mut [f64],
290        count: Option<&'a mut usize>,
291    },
292    Booleans {
293        store: &'a mut [bool],
294        count: Option<&'a mut usize>,
295    },
296    Objects {
297        attrs: &'a mut [Attr<'a>],
298        maxlen: usize,
299        count: Option<&'a mut usize>,
300    },
301    StructObjects {
302        maxlen: usize,
303        count: Option<&'a mut usize>,
304        parser: &'a mut dyn FnMut(&str, usize) -> Result<usize>,
305    },
306}
307
308pub fn read_object(input: &str, attrs: &mut [Attr<'_>]) -> Result<usize> {
309    read_object_internal(input, attrs, None, 0)
310}
311
312pub fn read_array(input: &str, array: &mut Array<'_>) -> Result<usize> {
313    read_array_internal(input, array)
314}
315
316pub fn validate_json(input: &[u8]) -> Result<usize> {
317    let mut validator = JsonValidator {
318        bytes: input,
319        depth: 0,
320    };
321    let end = validator.parse_value(validator.skip_ws(0))?;
322    let end = validator.skip_ws(end);
323    if end == input.len() {
324        Ok(end)
325    } else {
326        Err(Error::BadTrail)
327    }
328}
329
330pub fn cstr(buf: &[u8]) -> &str {
331    let len = buf.iter().position(|&b| b == 0).unwrap_or(buf.len());
332    core::str::from_utf8(&buf[..len]).unwrap_or("")
333}
334
335struct JsonValidator<'a> {
336    bytes: &'a [u8],
337    depth: usize,
338}
339
340impl JsonValidator<'_> {
341    const MAX_DEPTH: usize = 1024;
342
343    fn parse_value(&mut self, i: usize) -> Result<usize> {
344        if i >= self.bytes.len() {
345            return Err(Error::BadTrail);
346        }
347        match self.bytes[i] {
348            b'{' => self.parse_object(i),
349            b'[' => self.parse_array(i),
350            b'"' => self.parse_string(i),
351            b't' => self.parse_literal(i, b"true"),
352            b'f' => self.parse_literal(i, b"false"),
353            b'n' => self.parse_literal(i, b"null"),
354            b'-' | b'0'..=b'9' => self.parse_number(i),
355            _ => Err(Error::BadTrail),
356        }
357    }
358
359    fn parse_object(&mut self, mut i: usize) -> Result<usize> {
360        self.enter()?;
361        i += 1;
362        i = self.skip_ws(i);
363        if i < self.bytes.len() && self.bytes[i] == b'}' {
364            self.leave();
365            return Ok(i + 1);
366        }
367        loop {
368            if i >= self.bytes.len() || self.bytes[i] != b'"' {
369                self.leave();
370                return Err(Error::AttrStart);
371            }
372            i = self.parse_string(i)?;
373            i = self.skip_ws(i);
374            if i >= self.bytes.len() || self.bytes[i] != b':' {
375                self.leave();
376                return Err(Error::BadTrail);
377            }
378            i = self.parse_value(self.skip_ws(i + 1))?;
379            i = self.skip_ws(i);
380            if i >= self.bytes.len() {
381                self.leave();
382                return Err(Error::BadTrail);
383            }
384            match self.bytes[i] {
385                b',' => i = self.skip_ws(i + 1),
386                b'}' => {
387                    self.leave();
388                    return Ok(i + 1);
389                }
390                _ => {
391                    self.leave();
392                    return Err(Error::BadTrail);
393                }
394            }
395        }
396    }
397
398    fn parse_array(&mut self, mut i: usize) -> Result<usize> {
399        self.enter()?;
400        i += 1;
401        i = self.skip_ws(i);
402        if i < self.bytes.len() && self.bytes[i] == b']' {
403            self.leave();
404            return Ok(i + 1);
405        }
406        loop {
407            i = self.parse_value(i)?;
408            i = self.skip_ws(i);
409            if i >= self.bytes.len() {
410                self.leave();
411                return Err(Error::BadTrail);
412            }
413            match self.bytes[i] {
414                b',' => i = self.skip_ws(i + 1),
415                b']' => {
416                    self.leave();
417                    return Ok(i + 1);
418                }
419                _ => {
420                    self.leave();
421                    return Err(Error::BadTrail);
422                }
423            }
424        }
425    }
426
427    fn parse_string(&self, mut i: usize) -> Result<usize> {
428        i += 1;
429        let mut raw_start = i;
430        while i < self.bytes.len() {
431            match self.bytes[i] {
432                b'"' => {
433                    core::str::from_utf8(&self.bytes[raw_start..i])
434                        .map_err(|_| Error::BadString)?;
435                    return Ok(i + 1);
436                }
437                b'\\' => {
438                    core::str::from_utf8(&self.bytes[raw_start..i])
439                        .map_err(|_| Error::BadString)?;
440                    i += 1;
441                    if i >= self.bytes.len() {
442                        return Err(Error::BadString);
443                    }
444                    match self.bytes[i] {
445                        b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {
446                            i += 1;
447                        }
448                        b'u' => {
449                            i += 1;
450                            for _ in 0..4 {
451                                if i >= self.bytes.len() || hex_val(self.bytes[i]).is_none() {
452                                    return Err(Error::BadString);
453                                }
454                                i += 1;
455                            }
456                        }
457                        _ => return Err(Error::BadString),
458                    }
459                    raw_start = i;
460                }
461                0x00..=0x1f => return Err(Error::BadString),
462                _ => i += 1,
463            }
464        }
465        Err(Error::BadString)
466    }
467
468    fn parse_literal(&self, i: usize, literal: &[u8]) -> Result<usize> {
469        if self.bytes[i..].starts_with(literal) {
470            Ok(i + literal.len())
471        } else {
472            Err(Error::BadTrail)
473        }
474    }
475
476    fn parse_number(&self, mut i: usize) -> Result<usize> {
477        if i < self.bytes.len() && self.bytes[i] == b'-' {
478            i += 1;
479        }
480        if i >= self.bytes.len() {
481            return Err(Error::BadNum);
482        }
483        if self.bytes[i] == b'0' {
484            i += 1;
485            if i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
486                return Err(Error::BadNum);
487            }
488        } else if self.bytes[i].is_ascii_digit() {
489            while i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
490                i += 1;
491            }
492        } else {
493            return Err(Error::BadNum);
494        }
495        if i < self.bytes.len() && self.bytes[i] == b'.' {
496            i += 1;
497            let start = i;
498            while i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
499                i += 1;
500            }
501            if i == start {
502                return Err(Error::BadNum);
503            }
504        }
505        if i < self.bytes.len() && matches!(self.bytes[i], b'e' | b'E') {
506            i += 1;
507            if i < self.bytes.len() && matches!(self.bytes[i], b'+' | b'-') {
508                i += 1;
509            }
510            let start = i;
511            while i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
512                i += 1;
513            }
514            if i == start {
515                return Err(Error::BadNum);
516            }
517        }
518        Ok(i)
519    }
520
521    fn skip_ws(&self, mut i: usize) -> usize {
522        while i < self.bytes.len() && matches!(self.bytes[i], b' ' | b'\t' | b'\n' | b'\r') {
523            i += 1;
524        }
525        i
526    }
527
528    fn enter(&mut self) -> Result<()> {
529        self.depth += 1;
530        if self.depth > Self::MAX_DEPTH {
531            return Err(Error::SubTooLong);
532        }
533        Ok(())
534    }
535
536    fn leave(&mut self) {
537        self.depth -= 1;
538    }
539}
540
541fn read_object_internal(
542    input: &str,
543    attrs: &mut [Attr<'_>],
544    parent_is_structobject: Option<bool>,
545    offset: usize,
546) -> Result<usize> {
547    apply_defaults(attrs, parent_is_structobject, offset)?;
548
549    let bytes = input.as_bytes();
550    let mut i = skip_ws(bytes, 0);
551    if i >= bytes.len() {
552        return Err(Error::Empty);
553    }
554    if bytes[i] != b'{' {
555        return Err(Error::ObStart);
556    }
557    i += 1;
558
559    loop {
560        i = skip_ws(bytes, i);
561        if i >= bytes.len() {
562            return Err(Error::AttrStart);
563        }
564        if bytes[i] == b'}' {
565            i += 1;
566            return Ok(skip_ws(bytes, i));
567        }
568        if bytes[i] != b'"' {
569            return Err(Error::AttrStart);
570        }
571        i += 1;
572
573        let mut attr_buf = [0u8; JSON_ATTR_MAX + 1];
574        let attr_len = parse_attr_name(bytes, &mut i, &mut attr_buf)?;
575        let attr_name = core::str::from_utf8(&attr_buf[..attr_len]).map_err(|_| Error::BadAttr)?;
576        let first = find_attr(attrs, attr_name).ok_or(Error::BadAttr)?;
577
578        i = skip_ws(bytes, i);
579        if i < bytes.len() && bytes[i] == b':' {
580            i += 1;
581        }
582        i = skip_ws(bytes, i);
583        if i >= bytes.len() {
584            return Err(Error::BadTrail);
585        }
586
587        if bytes[i] == b'[' {
588            if !matches!(attrs[first].kind, AttrKind::Array(_)) {
589                return Err(Error::NoArray);
590            }
591            let AttrKind::Array(array) = &mut attrs[first].kind else {
592                unreachable!();
593            };
594            i += read_array_internal(&input[i..], array)?;
595            i = skip_ws(bytes, i);
596        } else if matches!(attrs[first].kind, AttrKind::Array(_)) {
597            return Err(Error::NoBrak);
598        } else if bytes[i] == b'{' {
599            if !matches!(attrs[first].kind, AttrKind::Object(_)) {
600                return Err(Error::NoArray);
601            }
602            let AttrKind::Object(child) = &mut attrs[first].kind else {
603                unreachable!();
604            };
605            i += read_object_internal(&input[i..], child, None, 0)?;
606            i = skip_ws(bytes, i);
607        } else if matches!(attrs[first].kind, AttrKind::Object(_)) {
608            return Err(Error::NoCurly);
609        } else {
610            let mut val_buf = [0u8; JSON_VAL_MAX + 1];
611            let quoted = if bytes[i] == b'"' {
612                i += 1;
613                let maxlen = value_max_len(&attrs[first]);
614                parse_string_value(bytes, &mut i, &mut val_buf, maxlen)?;
615                true
616            } else {
617                parse_token_value(bytes, &mut i, &mut val_buf)?;
618                false
619            };
620            let selected = select_attr(attrs, first, attr_name, &val_buf, quoted)?;
621            apply_value(
622                &mut attrs[selected],
623                parent_is_structobject,
624                offset,
625                &val_buf,
626                quoted,
627            )?;
628            i = skip_ws(bytes, i);
629        }
630
631        if i >= bytes.len() {
632            return Err(Error::BadTrail);
633        }
634        if bytes[i] == b',' {
635            i += 1;
636        } else if bytes[i] == b'}' {
637            i += 1;
638            return Ok(skip_ws(bytes, i));
639        } else {
640            return Err(Error::BadTrail);
641        }
642    }
643}
644
645fn read_array_internal(input: &str, array: &mut Array<'_>) -> Result<usize> {
646    let bytes = input.as_bytes();
647    let mut i = skip_ws(bytes, 0);
648    if i >= bytes.len() || bytes[i] != b'[' {
649        return Err(Error::ArrayStart);
650    }
651    i += 1;
652    i = skip_ws(bytes, i);
653    if i < bytes.len() && bytes[i] == b']' {
654        set_array_count(array, 0);
655        return Ok(skip_ws(bytes, i + 1));
656    }
657
658    let maxlen = array_maxlen(array);
659    let mut count = 0usize;
660    while count < maxlen {
661        i = skip_ws(bytes, i);
662        match array {
663            Array::Strings { store, .. } => {
664                if i >= bytes.len() || bytes[i] != b'"' {
665                    return Err(Error::BadString);
666                }
667                i += 1;
668                parse_string_value(
669                    bytes,
670                    &mut i,
671                    store[count],
672                    store[count].len().saturating_sub(1),
673                )?;
674            }
675            Array::Integers { store, .. } => {
676                let (v, end) = parse_i32_at(bytes, i)?;
677                store[count] = v;
678                i = end;
679            }
680            Array::UIntegers { store, .. } => {
681                let (v, end) = parse_u32_at(bytes, i)?;
682                store[count] = v;
683                i = end;
684            }
685            Array::Shorts { store, .. } => {
686                let (v, end) = parse_i16_at(bytes, i)?;
687                store[count] = v;
688                i = end;
689            }
690            Array::UShorts { store, .. } => {
691                let (v, end) = parse_u16_at(bytes, i)?;
692                store[count] = v;
693                i = end;
694            }
695            Array::Reals { store, .. } => {
696                let (v, end) = parse_f64_at(bytes, i)?;
697                store[count] = v;
698                i = end;
699            }
700            Array::Booleans { store, .. } => {
701                let (v, end) = parse_bool_at(bytes, i)?;
702                store[count] = v;
703                i = end;
704            }
705            Array::Objects { attrs, .. } => {
706                i += read_object_internal(&input[i..], attrs, Some(false), count)?;
707            }
708            Array::StructObjects { parser, .. } => {
709                i += parser(&input[i..], count)?;
710            }
711        }
712        count += 1;
713        i = skip_ws(bytes, i);
714        if i < bytes.len() && bytes[i] == b']' {
715            set_array_count(array, count);
716            return Ok(skip_ws(bytes, i + 1));
717        }
718        if i < bytes.len() && bytes[i] == b',' {
719            i += 1;
720        } else {
721            return Err(Error::BadSubTrail);
722        }
723    }
724
725    Err(Error::SubTooLong)
726}
727
728fn apply_defaults(
729    attrs: &mut [Attr<'_>],
730    parent_is_structobject: Option<bool>,
731    offset: usize,
732) -> Result<()> {
733    for attr in attrs {
734        if attr.nodefault {
735            continue;
736        }
737        match attr.default {
738            DefaultValue::None => {
739                if let AttrKind::String(buf) = &mut attr.kind {
740                    if matches!(parent_is_structobject, Some(false)) && offset > 0 {
741                        return Err(Error::NoParStr);
742                    }
743                    clear_cbuf(buf);
744                }
745            }
746            DefaultValue::Integer(v) => set_i32(&mut attr.kind, offset, v)?,
747            DefaultValue::UInteger(v) => set_u32(&mut attr.kind, offset, v)?,
748            DefaultValue::Short(v) => set_i16(&mut attr.kind, offset, v)?,
749            DefaultValue::UShort(v) => set_u16(&mut attr.kind, offset, v)?,
750            DefaultValue::Real(v) => set_f64(&mut attr.kind, offset, v)?,
751            DefaultValue::Boolean(v) => set_bool(&mut attr.kind, offset, v)?,
752            DefaultValue::Character(v) => set_char(&mut attr.kind, offset, v)?,
753            DefaultValue::Check(_) => {}
754        }
755    }
756    Ok(())
757}
758
759fn parse_attr_name(
760    bytes: &[u8],
761    i: &mut usize,
762    out: &mut [u8; JSON_ATTR_MAX + 1],
763) -> Result<usize> {
764    let mut len = 0usize;
765    while *i < bytes.len() {
766        let b = bytes[*i];
767        *i += 1;
768        if b == b'"' {
769            return Ok(len);
770        }
771        if len >= JSON_ATTR_MAX {
772            return Err(Error::AttrLen);
773        }
774        out[len] = b;
775        len += 1;
776    }
777    Err(Error::BadString)
778}
779
780fn parse_string_value(
781    bytes: &[u8],
782    i: &mut usize,
783    out: &mut [u8],
784    max_content_len: usize,
785) -> Result<usize> {
786    clear_cbuf(out);
787    let mut len = 0usize;
788    while *i < bytes.len() {
789        let b = bytes[*i];
790        *i += 1;
791        let outb = if b == b'\\' {
792            if *i >= bytes.len() {
793                return Err(Error::BadString);
794            }
795            let e = bytes[*i];
796            *i += 1;
797            match e {
798                b'b' => 8,
799                b'f' => 12,
800                b'n' => b'\n',
801                b'r' => b'\r',
802                b't' => b'\t',
803                b'u' => {
804                    if *i + 4 > bytes.len() {
805                        return Err(Error::BadString);
806                    }
807                    let mut v = 0u32;
808                    for _ in 0..4 {
809                        let Some(d) = hex_val(bytes[*i]) else {
810                            return Err(Error::BadString);
811                        };
812                        v = (v << 4) | d as u32;
813                        *i += 1;
814                    }
815                    v as u8
816                }
817                other => other,
818            }
819        } else if b == b'"' {
820            if len < out.len() {
821                out[len] = 0;
822            }
823            return Ok(len);
824        } else {
825            b
826        };
827        if len >= JSON_VAL_MAX || len >= max_content_len || len + 1 > out.len() {
828            return Err(Error::StrLong);
829        }
830        out[len] = outb;
831        len += 1;
832    }
833    Err(Error::BadString)
834}
835
836fn parse_token_value(
837    bytes: &[u8],
838    i: &mut usize,
839    out: &mut [u8; JSON_VAL_MAX + 1],
840) -> Result<usize> {
841    let mut len = 0usize;
842    while *i < bytes.len() {
843        let b = bytes[*i];
844        if is_ws(b) || b == b',' || b == b'}' || b == b']' {
845            out[len] = 0;
846            return Ok(len);
847        }
848        if len >= JSON_VAL_MAX {
849            return Err(Error::TokLong);
850        }
851        out[len] = b;
852        len += 1;
853        *i += 1;
854    }
855    out[len] = 0;
856    Ok(len)
857}
858
859fn find_attr(attrs: &[Attr<'_>], name: &str) -> Option<usize> {
860    let mut ignore = None;
861    for (idx, attr) in attrs.iter().enumerate() {
862        if attr.name == name {
863            return Some(idx);
864        }
865        if attr.name.is_empty() && matches!(attr.kind, AttrKind::Ignore) {
866            ignore = Some(idx);
867        }
868    }
869    ignore
870}
871
872fn select_attr(
873    attrs: &[Attr<'_>],
874    first: usize,
875    name: &str,
876    val: &[u8; JSON_VAL_MAX + 1],
877    quoted: bool,
878) -> Result<usize> {
879    let mut idx = first;
880    loop {
881        if value_fits_attr(&attrs[idx], val, quoted) {
882            break;
883        }
884        if idx + 1 >= attrs.len() || attrs[idx + 1].name != name {
885            break;
886        }
887        idx += 1;
888    }
889
890    let attr = &attrs[idx];
891    if quoted
892        && !matches!(
893            attr.kind,
894            AttrKind::String(_)
895                | AttrKind::Character(_)
896                | AttrKind::Check(_)
897                | AttrKind::Time(_)
898                | AttrKind::Ignore
899        )
900        && attr.map.is_none()
901    {
902        return Err(Error::QNonString);
903    }
904    if !quoted
905        && (matches!(
906            attr.kind,
907            AttrKind::String(_) | AttrKind::Check(_) | AttrKind::Time(_)
908        ) || attr.map.is_some())
909    {
910        return Err(Error::NonQString);
911    }
912    Ok(idx)
913}
914
915fn value_fits_attr(attr: &Attr<'_>, val: &[u8; JSON_VAL_MAX + 1], quoted: bool) -> bool {
916    if quoted {
917        return matches!(attr.kind, AttrKind::String(_) | AttrKind::Time(_));
918    }
919    if token_eq(val, b"true") || token_eq(val, b"false") {
920        return matches!(attr.kind, AttrKind::Boolean(_));
921    }
922    if json_number_is_integer(val) {
923        return matches!(
924            attr.kind,
925            AttrKind::Integer(_) | AttrKind::UInteger(_) | AttrKind::Short(_) | AttrKind::UShort(_)
926        );
927    }
928    if json_number_is_real(val) {
929        return matches!(attr.kind, AttrKind::Real(_));
930    }
931    false
932}
933
934fn apply_value(
935    attr: &mut Attr<'_>,
936    parent_is_structobject: Option<bool>,
937    offset: usize,
938    val: &[u8; JSON_VAL_MAX + 1],
939    _quoted: bool,
940) -> Result<()> {
941    let mut mapped_buf = [0u8; JSON_VAL_MAX + 1];
942    let val = if let Some(map) = attr.map {
943        let s = token_str(val)?;
944        let mut found = None;
945        for item in map {
946            if item.name == s {
947                found = Some(item.value);
948                break;
949            }
950        }
951        let Some(found) = found else {
952            return Err(Error::BadEnum);
953        };
954        write_i32_token(found, &mut mapped_buf);
955        &mapped_buf
956    } else {
957        val
958    };
959
960    match &mut attr.kind {
961        AttrKind::Integer(_) => {
962            let v = parse_i32_token(val)?;
963            set_i32(&mut attr.kind, offset, v)
964        }
965        AttrKind::UInteger(_) => {
966            let v = parse_u32_token(val)?;
967            set_u32(&mut attr.kind, offset, v)
968        }
969        AttrKind::Short(_) => {
970            let v = parse_i16_token(val)?;
971            set_i16(&mut attr.kind, offset, v)
972        }
973        AttrKind::UShort(_) => {
974            let v = parse_u16_token(val)?;
975            set_u16(&mut attr.kind, offset, v)
976        }
977        AttrKind::Real(_) => {
978            let v = parse_f64_token(val)?;
979            set_f64(&mut attr.kind, offset, v)
980        }
981        AttrKind::String(buf) => {
982            if matches!(parent_is_structobject, Some(false)) && offset > 0 {
983                return Err(Error::NoParStr);
984            }
985            copy_cbuf(buf, val);
986            Ok(())
987        }
988        AttrKind::Boolean(_) => {
989            let v = if token_eq(val, b"true") {
990                true
991            } else if token_eq(val, b"false") {
992                false
993            } else {
994                parse_i64_token(val)? != 0
995            };
996            set_bool(&mut attr.kind, offset, v)
997        }
998        AttrKind::Character(_) => {
999            let len = token_len(val);
1000            if len > 1 {
1001                return Err(Error::StrLong);
1002            }
1003            set_char(&mut attr.kind, offset, if len == 0 { 0 } else { val[0] })
1004        }
1005        AttrKind::Check(expected) => {
1006            if token_str(val)? == *expected {
1007                Ok(())
1008            } else {
1009                Err(Error::CheckFail)
1010            }
1011        }
1012        AttrKind::Ignore => Ok(()),
1013        AttrKind::Time(_) => Ok(()),
1014        AttrKind::Object(_) | AttrKind::Array(_) => Ok(()),
1015    }
1016}
1017
1018fn set_i32(kind: &mut AttrKind<'_>, offset: usize, value: i32) -> Result<()> {
1019    if let AttrKind::Integer(target) = kind {
1020        target.set(offset, value)?;
1021    }
1022    Ok(())
1023}
1024
1025fn set_u32(kind: &mut AttrKind<'_>, offset: usize, value: u32) -> Result<()> {
1026    if let AttrKind::UInteger(target) = kind {
1027        target.set(offset, value)?;
1028    }
1029    Ok(())
1030}
1031
1032fn set_i16(kind: &mut AttrKind<'_>, offset: usize, value: i16) -> Result<()> {
1033    if let AttrKind::Short(target) = kind {
1034        target.set(offset, value)?;
1035    }
1036    Ok(())
1037}
1038
1039fn set_u16(kind: &mut AttrKind<'_>, offset: usize, value: u16) -> Result<()> {
1040    if let AttrKind::UShort(target) = kind {
1041        target.set(offset, value)?;
1042    }
1043    Ok(())
1044}
1045
1046fn set_f64(kind: &mut AttrKind<'_>, offset: usize, value: f64) -> Result<()> {
1047    match kind {
1048        AttrKind::Real(target) | AttrKind::Time(target) => target.set(offset, value)?,
1049        _ => {}
1050    }
1051    Ok(())
1052}
1053
1054fn set_bool(kind: &mut AttrKind<'_>, offset: usize, value: bool) -> Result<()> {
1055    if let AttrKind::Boolean(target) = kind {
1056        target.set(offset, value)?;
1057    }
1058    Ok(())
1059}
1060
1061fn set_char(kind: &mut AttrKind<'_>, offset: usize, value: u8) -> Result<()> {
1062    if let AttrKind::Character(target) = kind {
1063        target.set(offset, value)?;
1064    }
1065    Ok(())
1066}
1067
1068fn value_max_len(attr: &Attr<'_>) -> usize {
1069    match &attr.kind {
1070        AttrKind::String(buf) => buf.len().saturating_sub(1),
1071        AttrKind::Check(expected) => expected.len(),
1072        AttrKind::Time(_) | AttrKind::Ignore => JSON_VAL_MAX,
1073        _ if attr.map.is_some() => JSON_VAL_MAX,
1074        _ => JSON_VAL_MAX,
1075    }
1076}
1077
1078fn array_maxlen(array: &Array<'_>) -> usize {
1079    match array {
1080        Array::Strings { store, .. } => store.len(),
1081        Array::Integers { store, .. } => store.len(),
1082        Array::UIntegers { store, .. } => store.len(),
1083        Array::Shorts { store, .. } => store.len(),
1084        Array::UShorts { store, .. } => store.len(),
1085        Array::Reals { store, .. } => store.len(),
1086        Array::Booleans { store, .. } => store.len(),
1087        Array::Objects { maxlen, .. } => *maxlen,
1088        Array::StructObjects { maxlen, .. } => *maxlen,
1089    }
1090}
1091
1092fn set_array_count(array: &mut Array<'_>, value: usize) {
1093    match array {
1094        Array::Strings { count, .. }
1095        | Array::Integers { count, .. }
1096        | Array::UIntegers { count, .. }
1097        | Array::Shorts { count, .. }
1098        | Array::UShorts { count, .. }
1099        | Array::Reals { count, .. }
1100        | Array::Booleans { count, .. }
1101        | Array::Objects { count, .. }
1102        | Array::StructObjects { count, .. } => {
1103            if let Some(count) = count {
1104                **count = value;
1105            }
1106        }
1107    }
1108}
1109
1110fn skip_ws(bytes: &[u8], mut i: usize) -> usize {
1111    while i < bytes.len() && is_ws(bytes[i]) {
1112        i += 1;
1113    }
1114    i
1115}
1116
1117fn is_ws(b: u8) -> bool {
1118    matches!(b, b' ' | b'\t' | b'\n' | b'\r' | 0x0c | 0x0b)
1119}
1120
1121fn clear_cbuf(buf: &mut [u8]) {
1122    for b in buf {
1123        *b = 0;
1124    }
1125}
1126
1127fn copy_cbuf(out: &mut [u8], val: &[u8; JSON_VAL_MAX + 1]) {
1128    clear_cbuf(out);
1129    if out.is_empty() {
1130        return;
1131    }
1132    let n = core::cmp::min(token_len(val), out.len() - 1);
1133    out[..n].copy_from_slice(&val[..n]);
1134}
1135
1136fn token_len(token: &[u8]) -> usize {
1137    token.iter().position(|&b| b == 0).unwrap_or(token.len())
1138}
1139
1140fn token_str(token: &[u8]) -> Result<&str> {
1141    core::str::from_utf8(&token[..token_len(token)]).map_err(|_| Error::BadString)
1142}
1143
1144fn token_eq(token: &[u8], expected: &[u8]) -> bool {
1145    &token[..token_len(token)] == expected
1146}
1147
1148fn hex_val(b: u8) -> Option<u8> {
1149    match b {
1150        b'0'..=b'9' => Some(b - b'0'),
1151        b'a'..=b'f' => Some(b - b'a' + 10),
1152        b'A'..=b'F' => Some(b - b'A' + 10),
1153        _ => None,
1154    }
1155}
1156
1157fn parse_i32_at(bytes: &[u8], start: usize) -> Result<(i32, usize)> {
1158    let end = number_end(bytes, start)?;
1159    Ok((parse_i32_bytes(&bytes[start..end])?, end))
1160}
1161
1162fn parse_u32_at(bytes: &[u8], start: usize) -> Result<(u32, usize)> {
1163    let end = number_end(bytes, start)?;
1164    Ok((parse_u32_bytes(&bytes[start..end])?, end))
1165}
1166
1167fn parse_i16_at(bytes: &[u8], start: usize) -> Result<(i16, usize)> {
1168    let end = number_end(bytes, start)?;
1169    let v = parse_i64_bytes(&bytes[start..end])?;
1170    if v < i16::MIN as i64 || v > i16::MAX as i64 {
1171        return Err(Error::BadNum);
1172    }
1173    Ok((v as i16, end))
1174}
1175
1176fn parse_u16_at(bytes: &[u8], start: usize) -> Result<(u16, usize)> {
1177    let end = number_end(bytes, start)?;
1178    let v = parse_u64_bytes(&bytes[start..end])?;
1179    if v > u16::MAX as u64 {
1180        return Err(Error::BadNum);
1181    }
1182    Ok((v as u16, end))
1183}
1184
1185fn parse_f64_at(bytes: &[u8], start: usize) -> Result<(f64, usize)> {
1186    let end = number_end(bytes, start)?;
1187    Ok((parse_f64_bytes(&bytes[start..end])?, end))
1188}
1189
1190fn parse_bool_at(bytes: &[u8], start: usize) -> Result<(bool, usize)> {
1191    if bytes[start..].starts_with(b"true") {
1192        Ok((true, start + 4))
1193    } else if bytes[start..].starts_with(b"false") {
1194        Ok((false, start + 5))
1195    } else {
1196        let (v, end) = parse_i32_at(bytes, start)?;
1197        Ok((v != 0, end))
1198    }
1199}
1200
1201fn number_end(bytes: &[u8], mut i: usize) -> Result<usize> {
1202    let start = i;
1203    if i < bytes.len() && bytes[i] == b'-' {
1204        i += 1;
1205    }
1206    let mut saw_digit = false;
1207    while i < bytes.len() && bytes[i].is_ascii_digit() {
1208        saw_digit = true;
1209        i += 1;
1210    }
1211    if i < bytes.len() && bytes[i] == b'.' {
1212        i += 1;
1213        while i < bytes.len() && bytes[i].is_ascii_digit() {
1214            saw_digit = true;
1215            i += 1;
1216        }
1217    }
1218    if i < bytes.len() && matches!(bytes[i], b'e' | b'E') {
1219        i += 1;
1220        if i < bytes.len() && matches!(bytes[i], b'+' | b'-') {
1221            i += 1;
1222        }
1223        let exp_start = i;
1224        while i < bytes.len() && bytes[i].is_ascii_digit() {
1225            i += 1;
1226        }
1227        if i == exp_start {
1228            return Err(Error::BadNum);
1229        }
1230    }
1231    if !saw_digit || i == start {
1232        Err(Error::BadNum)
1233    } else {
1234        Ok(i)
1235    }
1236}
1237
1238fn parse_i32_token(token: &[u8]) -> Result<i32> {
1239    parse_i32_bytes(&token[..token_len(token)])
1240}
1241
1242fn parse_u32_token(token: &[u8]) -> Result<u32> {
1243    parse_u32_bytes(&token[..token_len(token)])
1244}
1245
1246fn parse_i16_token(token: &[u8]) -> Result<i16> {
1247    let v = parse_i64_token(token)?;
1248    if v < i16::MIN as i64 || v > i16::MAX as i64 {
1249        return Err(Error::BadNum);
1250    }
1251    Ok(v as i16)
1252}
1253
1254fn parse_u16_token(token: &[u8]) -> Result<u16> {
1255    let v = parse_u64_bytes(&token[..token_len(token)])?;
1256    if v > u16::MAX as u64 {
1257        return Err(Error::BadNum);
1258    }
1259    Ok(v as u16)
1260}
1261
1262fn parse_i64_token(token: &[u8]) -> Result<i64> {
1263    parse_i64_bytes(&token[..token_len(token)])
1264}
1265
1266fn parse_f64_token(token: &[u8]) -> Result<f64> {
1267    parse_f64_bytes(&token[..token_len(token)])
1268}
1269
1270fn parse_i32_bytes(bytes: &[u8]) -> Result<i32> {
1271    let v = parse_i64_bytes(bytes)?;
1272    if v < i32::MIN as i64 || v > i32::MAX as i64 {
1273        return Err(Error::BadNum);
1274    }
1275    Ok(v as i32)
1276}
1277
1278fn parse_u32_bytes(bytes: &[u8]) -> Result<u32> {
1279    let v = parse_u64_bytes(bytes)?;
1280    if v > u32::MAX as u64 {
1281        return Err(Error::BadNum);
1282    }
1283    Ok(v as u32)
1284}
1285
1286fn parse_i64_bytes(bytes: &[u8]) -> Result<i64> {
1287    let mut i = 0usize;
1288    let neg = bytes.first() == Some(&b'-');
1289    if neg {
1290        i = 1;
1291    }
1292    if i >= bytes.len() || bytes[i] == b'+' {
1293        return Err(Error::BadNum);
1294    }
1295    let mut v: i64 = 0;
1296    while i < bytes.len() {
1297        let b = bytes[i];
1298        if !b.is_ascii_digit() {
1299            return Err(Error::BadNum);
1300        }
1301        v = v.checked_mul(10).ok_or(Error::BadNum)?;
1302        v = v.checked_add((b - b'0') as i64).ok_or(Error::BadNum)?;
1303        i += 1;
1304    }
1305    if neg {
1306        v.checked_neg().ok_or(Error::BadNum)
1307    } else {
1308        Ok(v)
1309    }
1310}
1311
1312fn parse_u64_bytes(bytes: &[u8]) -> Result<u64> {
1313    if bytes.is_empty() || bytes[0] == b'-' || bytes[0] == b'+' {
1314        return Err(Error::BadNum);
1315    }
1316    let mut v: u64 = 0;
1317    for &b in bytes {
1318        if !b.is_ascii_digit() {
1319            return Err(Error::BadNum);
1320        }
1321        v = v.checked_mul(10).ok_or(Error::BadNum)?;
1322        v = v.checked_add((b - b'0') as u64).ok_or(Error::BadNum)?;
1323    }
1324    Ok(v)
1325}
1326
1327fn parse_f64_bytes(bytes: &[u8]) -> Result<f64> {
1328    if bytes.is_empty() {
1329        return Err(Error::BadNum);
1330    }
1331    let mut i = 0usize;
1332    let neg = bytes[i] == b'-';
1333    if neg {
1334        i += 1;
1335    }
1336    if i >= bytes.len() {
1337        return Err(Error::BadNum);
1338    }
1339    let mut value = 0f64;
1340    let int_start = i;
1341    if bytes[i] == b'0' {
1342        i += 1;
1343        if i < bytes.len() && bytes[i].is_ascii_digit() {
1344            return Err(Error::BadNum);
1345        }
1346    } else {
1347        while i < bytes.len() && bytes[i].is_ascii_digit() {
1348            value = value * 10.0 + (bytes[i] - b'0') as f64;
1349            i += 1;
1350        }
1351    }
1352    if i == int_start {
1353        return Err(Error::BadNum);
1354    }
1355    if i < bytes.len() && bytes[i] == b'.' {
1356        i += 1;
1357        let frac_start = i;
1358        let mut scale = 0.1f64;
1359        while i < bytes.len() && bytes[i].is_ascii_digit() {
1360            value += (bytes[i] - b'0') as f64 * scale;
1361            scale *= 0.1;
1362            i += 1;
1363        }
1364        if i == frac_start {
1365            return Err(Error::BadNum);
1366        }
1367    }
1368    if i < bytes.len() && matches!(bytes[i], b'e' | b'E') {
1369        i += 1;
1370        let exp_neg = if i < bytes.len() && matches!(bytes[i], b'+' | b'-') {
1371            let n = bytes[i] == b'-';
1372            i += 1;
1373            n
1374        } else {
1375            false
1376        };
1377        let exp_start = i;
1378        let mut exp = 0i32;
1379        while i < bytes.len() && bytes[i].is_ascii_digit() {
1380            exp = exp
1381                .saturating_mul(10)
1382                .saturating_add((bytes[i] - b'0') as i32);
1383            i += 1;
1384        }
1385        if i == exp_start {
1386            return Err(Error::BadNum);
1387        }
1388        value *= pow10(if exp_neg { -exp } else { exp });
1389    }
1390    if i != bytes.len() {
1391        return Err(Error::BadNum);
1392    }
1393    Ok(if neg { -value } else { value })
1394}
1395
1396fn pow10(exp: i32) -> f64 {
1397    let mut n = if exp < 0 { -exp } else { exp };
1398    let mut base = 10.0f64;
1399    let mut result = 1.0f64;
1400    while n > 0 {
1401        if n & 1 == 1 {
1402            result *= base;
1403        }
1404        base *= base;
1405        n >>= 1;
1406    }
1407    if exp < 0 { 1.0 / result } else { result }
1408}
1409
1410fn json_number_is_integer(token: &[u8]) -> bool {
1411    let bytes = &token[..token_len(token)];
1412    match_json_number(bytes).is_some_and(|is_integer| is_integer)
1413}
1414
1415fn json_number_is_real(token: &[u8]) -> bool {
1416    let bytes = &token[..token_len(token)];
1417    match_json_number(bytes).is_some_and(|is_integer| !is_integer)
1418}
1419
1420fn match_json_number(bytes: &[u8]) -> Option<bool> {
1421    if bytes.is_empty() {
1422        return None;
1423    }
1424    let mut i = 0usize;
1425    let mut saw_fraction = false;
1426    let mut saw_exponent = false;
1427    if bytes[i] == b'-' {
1428        i += 1;
1429    }
1430    if i >= bytes.len() || !bytes[i].is_ascii_digit() {
1431        return None;
1432    }
1433    if bytes[i] == b'0' {
1434        i += 1;
1435        if i < bytes.len() && bytes[i].is_ascii_digit() {
1436            return None;
1437        }
1438    } else {
1439        while i < bytes.len() && bytes[i].is_ascii_digit() {
1440            i += 1;
1441        }
1442    }
1443    if i < bytes.len() && bytes[i] == b'.' {
1444        saw_fraction = true;
1445        i += 1;
1446        if i >= bytes.len() || !bytes[i].is_ascii_digit() {
1447            return None;
1448        }
1449        while i < bytes.len() && bytes[i].is_ascii_digit() {
1450            i += 1;
1451        }
1452    }
1453    if i < bytes.len() && matches!(bytes[i], b'e' | b'E') {
1454        saw_exponent = true;
1455        i += 1;
1456        if i < bytes.len() && matches!(bytes[i], b'+' | b'-') {
1457            i += 1;
1458        }
1459        if i >= bytes.len() || !bytes[i].is_ascii_digit() {
1460            return None;
1461        }
1462        while i < bytes.len() && bytes[i].is_ascii_digit() {
1463            i += 1;
1464        }
1465    }
1466    if i == bytes.len() {
1467        Some(!(saw_fraction || saw_exponent))
1468    } else {
1469        None
1470    }
1471}
1472
1473fn write_i32_token(mut value: i32, out: &mut [u8; JSON_VAL_MAX + 1]) {
1474    clear_cbuf(out);
1475    if value == 0 {
1476        out[0] = b'0';
1477        return;
1478    }
1479    let mut tmp = [0u8; 12];
1480    let neg = value < 0;
1481    let mut i = tmp.len();
1482    while value != 0 {
1483        let digit = (value % 10).unsigned_abs() as u8;
1484        i -= 1;
1485        tmp[i] = b'0' + digit;
1486        value /= 10;
1487    }
1488    if neg {
1489        i -= 1;
1490        tmp[i] = b'-';
1491    }
1492    let n = tmp.len() - i;
1493    out[..n].copy_from_slice(&tmp[i..]);
1494}
1495
1496#[cfg(test)]
1497#[allow(clippy::drop_non_drop)]
1498mod tests {
1499    use super::*;
1500
1501    #[test]
1502    fn parses_basic_object() {
1503        let mut count = 0;
1504        let mut flag1 = false;
1505        let mut flag2 = true;
1506        let mut attrs = [
1507            Attr::integer("count", &mut count),
1508            Attr::boolean("flag1", &mut flag1),
1509            Attr::boolean("flag2", &mut flag2),
1510        ];
1511
1512        let end = read_object(r#"{"flag2":false,"count":7,"flag1":true}"#, &mut attrs).unwrap();
1513        drop(attrs);
1514        assert_eq!(end, 38);
1515        assert_eq!(count, 7);
1516        assert!(flag1);
1517        assert!(!flag2);
1518    }
1519
1520    #[test]
1521    fn parses_object_array_into_parallel_slices() {
1522        let mut prn = [0; 4];
1523        let mut el = [0; 4];
1524        let mut used = [false; 4];
1525        let mut count = 0;
1526        let mut sat_attrs = [
1527            Attr::integers("PRN", &mut prn),
1528            Attr::integers("el", &mut el),
1529            Attr::booleans("used", &mut used),
1530        ];
1531        let mut attrs = [Attr::array(
1532            "satellites",
1533            Array::Objects {
1534                attrs: &mut sat_attrs,
1535                maxlen: 4,
1536                count: Some(&mut count),
1537            },
1538        )];
1539
1540        read_object(
1541            r#"{"satellites":[{"PRN":10,"el":45,"used":true},{"PRN":21,"el":10,"used":false}]}"#,
1542            &mut attrs,
1543        )
1544        .unwrap();
1545        drop(attrs);
1546        assert_eq!(count, 2);
1547        assert_eq!(prn[..2], [10, 21]);
1548        assert_eq!(el[..2], [45, 10]);
1549        assert_eq!(used[..2], [true, false]);
1550    }
1551
1552    #[test]
1553    fn parses_concatenated_objects() {
1554        let mut flag = false;
1555        let input = r#"{"flag":true} {"flag":0}"#;
1556        let mut attrs = [Attr::boolean("flag", &mut flag)];
1557        let end = read_object(input, &mut attrs).unwrap();
1558        assert_eq!(end, 14);
1559        read_object(&input[end..], &mut attrs).unwrap();
1560        drop(attrs);
1561        assert!(!flag);
1562    }
1563
1564    #[test]
1565    fn applies_defaults_for_omitted_fields() {
1566        let mut flag1 = false;
1567        let mut flag2 = true;
1568        let mut dftint = 0;
1569        let mut dftuint = 0;
1570        let mut dftshort = 0;
1571        let mut dftushort = 0;
1572        let mut dftreal = 0.0;
1573        let mut dftchar = 0;
1574        let mut attrs = [
1575            Attr::integer("dftint", &mut dftint).with_default(DefaultValue::Integer(-5)),
1576            Attr::uinteger("dftuint", &mut dftuint).with_default(DefaultValue::UInteger(10)),
1577            Attr::short("dftshort", &mut dftshort).with_default(DefaultValue::Short(-12)),
1578            Attr::ushort("dftushort", &mut dftushort).with_default(DefaultValue::UShort(12)),
1579            Attr::real("dftreal", &mut dftreal).with_default(DefaultValue::Real(23.17)),
1580            Attr::character("dftchar", &mut dftchar).with_default(DefaultValue::Character(b'X')),
1581            Attr::boolean("flag1", &mut flag1),
1582            Attr::boolean("flag2", &mut flag2),
1583        ];
1584
1585        read_object(r#"{"flag1":true,"flag2":false}"#, &mut attrs).unwrap();
1586        drop(attrs);
1587        assert_eq!(dftint, -5);
1588        assert_eq!(dftuint, 10);
1589        assert_eq!(dftshort, -12);
1590        assert_eq!(dftushort, 12);
1591        assert_eq!(dftreal, 23.17);
1592        assert_eq!(dftchar, b'X');
1593        assert!(flag1);
1594        assert!(!flag2);
1595    }
1596
1597    #[test]
1598    fn nodefault_leaves_existing_value_untouched() {
1599        let mut count = 99;
1600        let mut attrs = [Attr::integer("count", &mut count)
1601            .with_default(DefaultValue::Integer(-1))
1602            .nodefault()];
1603
1604        read_object(r#"{}"#, &mut attrs).unwrap();
1605        drop(attrs);
1606        assert_eq!(count, 99);
1607    }
1608
1609    #[test]
1610    fn parses_fixed_string_buffer_and_escapes() {
1611        let mut name = [b'!'; 16];
1612        let mut attrs = [Attr::string("name", &mut name)];
1613
1614        read_object(r#"{"name":"A\n\u0042\/\""}"#, &mut attrs).unwrap();
1615        drop(attrs);
1616        assert_eq!(cstr(&name), "A\nB/\"");
1617        assert_eq!(name[6], 0);
1618    }
1619
1620    #[test]
1621    fn rejects_string_that_would_overflow_destination() {
1622        let mut name = [0; 4];
1623        let mut attrs = [Attr::string("name", &mut name)];
1624
1625        let err = read_object(r#"{"name":"abcd"}"#, &mut attrs).unwrap_err();
1626        drop(attrs);
1627        assert_eq!(err, Error::StrLong);
1628        assert_eq!(cstr(&name), "");
1629    }
1630
1631    #[test]
1632    fn parses_character_field() {
1633        let mut ch = 0;
1634        let mut attrs = [Attr::character("parity", &mut ch)];
1635
1636        read_object(r#"{"parity":"N"}"#, &mut attrs).unwrap();
1637        drop(attrs);
1638        assert_eq!(ch, b'N');
1639    }
1640
1641    #[test]
1642    fn rejects_multi_byte_character_field() {
1643        let mut ch = 0;
1644        let mut attrs = [Attr::character("parity", &mut ch)];
1645
1646        let err = read_object(r#"{"parity":"NO"}"#, &mut attrs).unwrap_err();
1647        assert_eq!(err, Error::StrLong);
1648    }
1649
1650    #[test]
1651    fn check_fields_accept_expected_value_and_reject_others() {
1652        let mut mode = 0;
1653        let mut attrs = [
1654            Attr::check("class", "TPV"),
1655            Attr::integer("mode", &mut mode).with_default(DefaultValue::Integer(-9)),
1656        ];
1657
1658        read_object(r#"{"class":"TPV","mode":3}"#, &mut attrs).unwrap();
1659        drop(attrs);
1660        assert_eq!(mode, 3);
1661
1662        let mut mode = 19;
1663        let mut attrs = [
1664            Attr::check("class", "TPV"),
1665            Attr::integer("mode", &mut mode).with_default(DefaultValue::Integer(-9)),
1666        ];
1667        let err = read_object(r#"{"class":"foo","mode":-4}"#, &mut attrs).unwrap_err();
1668        drop(attrs);
1669        assert_eq!(err, Error::CheckFail);
1670        assert_eq!(mode, -9);
1671    }
1672
1673    #[test]
1674    fn ignore_any_accepts_unknown_attributes() {
1675        let mut enable = false;
1676        let mut json = false;
1677        let mut attrs = [
1678            Attr::check("class", "WATCH"),
1679            Attr::boolean("enable", &mut enable),
1680            Attr::boolean("json", &mut json),
1681            Attr::ignore_any(),
1682        ];
1683
1684        read_object(
1685            r#"{"class":"WATCH","enable":true,"json":true,"nmea":false,"raw":0,"device":"/dev/ttyUSB0"}"#,
1686            &mut attrs,
1687        )
1688        .unwrap();
1689        drop(attrs);
1690        assert!(enable);
1691        assert!(json);
1692    }
1693
1694    #[test]
1695    fn maps_quoted_enum_values_to_integers() {
1696        const MAP: &[EnumValue<'_>] = &[
1697            EnumValue {
1698                name: "BAR",
1699                value: 6,
1700            },
1701            EnumValue {
1702                name: "FOO",
1703                value: 3,
1704            },
1705            EnumValue {
1706                name: "BAZ",
1707                value: 14,
1708            },
1709        ];
1710        let mut fee = 0;
1711        let mut fie = 0;
1712        let mut foe = 0;
1713        let mut attrs = [
1714            Attr::integer("fee", &mut fee).with_map(MAP),
1715            Attr::integer("fie", &mut fie).with_map(MAP),
1716            Attr::integer("foe", &mut foe).with_map(MAP),
1717        ];
1718
1719        read_object(r#"{"fee":"FOO","fie":"BAR","foe":"BAZ"}"#, &mut attrs).unwrap();
1720        drop(attrs);
1721        assert_eq!((fee, fie, foe), (3, 6, 14));
1722    }
1723
1724    #[test]
1725    fn rejects_unknown_enum_value() {
1726        const MAP: &[EnumValue<'_>] = &[EnumValue {
1727            name: "SET",
1728            value: 1,
1729        }];
1730        let mut value = 0;
1731        let mut attrs = [Attr::integer("state", &mut value).with_map(MAP)];
1732
1733        let err = read_object(r#"{"state":"NOPE"}"#, &mut attrs).unwrap_err();
1734        assert_eq!(err, Error::BadEnum);
1735    }
1736
1737    #[test]
1738    fn parses_integer_boolean_real_and_string_arrays() {
1739        let mut ints = [0; 4];
1740        let mut int_count = 0;
1741        let mut int_array = Array::Integers {
1742            store: &mut ints,
1743            count: Some(&mut int_count),
1744        };
1745        read_array("[23,-17,5]", &mut int_array).unwrap();
1746        drop(int_array);
1747        assert_eq!(int_count, 3);
1748        assert_eq!(ints, [23, -17, 5, 0]);
1749
1750        let mut bools = [false; 4];
1751        let mut bool_count = 0;
1752        let mut bool_array = Array::Booleans {
1753            store: &mut bools,
1754            count: Some(&mut bool_count),
1755        };
1756        read_array("[true,false,7]", &mut bool_array).unwrap();
1757        drop(bool_array);
1758        assert_eq!(bool_count, 3);
1759        assert_eq!(bools, [true, false, true, false]);
1760
1761        let mut reals = [0.0; 4];
1762        let mut real_count = 0;
1763        let mut real_array = Array::Reals {
1764            store: &mut reals,
1765            count: Some(&mut real_count),
1766        };
1767        read_array("[23.1,-17.2,5.3e1]", &mut real_array).unwrap();
1768        drop(real_array);
1769        assert_eq!(real_count, 3);
1770        assert_eq!(reals[0], 23.1);
1771        assert_eq!(reals[1], -17.2);
1772        assert_eq!(reals[2], 53.0);
1773
1774        let mut s0 = [0; 8];
1775        let mut s1 = [0; 8];
1776        let mut s2 = [0; 8];
1777        let mut string_count = 0;
1778        {
1779            let mut strings: [&mut [u8]; 3] = [&mut s0, &mut s1, &mut s2];
1780            let mut string_array = Array::Strings {
1781                store: &mut strings,
1782                count: Some(&mut string_count),
1783            };
1784            read_array(r#"["foo","b\nr","\u0042az"]"#, &mut string_array).unwrap();
1785        }
1786        assert_eq!(string_count, 3);
1787        assert_eq!(cstr(&s0), "foo");
1788        assert_eq!(cstr(&s1), "b\nr");
1789        assert_eq!(cstr(&s2), "Baz");
1790    }
1791
1792    #[test]
1793    fn parses_unsigned_and_short_arrays() {
1794        let mut uints = [0; 3];
1795        let mut shorts = [0; 3];
1796        let mut ushorts = [0; 3];
1797
1798        let mut arr = Array::UIntegers {
1799            store: &mut uints,
1800            count: None,
1801        };
1802        read_array("[1,2,4294967295]", &mut arr).unwrap();
1803        drop(arr);
1804        assert_eq!(uints, [1, 2, u32::MAX]);
1805
1806        let mut arr = Array::Shorts {
1807            store: &mut shorts,
1808            count: None,
1809        };
1810        read_array("[-32768,0,32767]", &mut arr).unwrap();
1811        drop(arr);
1812        assert_eq!(shorts, [i16::MIN, 0, i16::MAX]);
1813
1814        let mut arr = Array::UShorts {
1815            store: &mut ushorts,
1816            count: None,
1817        };
1818        read_array("[0,65535,17]", &mut arr).unwrap();
1819        drop(arr);
1820        assert_eq!(ushorts, [0, u16::MAX, 17]);
1821    }
1822
1823    #[test]
1824    fn parses_nested_objects() {
1825        let mut name = [0; 16];
1826        let mut inner = 0;
1827        let mut innerinner = 0;
1828        let mut inner2_attrs = [Attr::integer("innerinner", &mut innerinner)];
1829        let mut inner1_attrs = [
1830            Attr::integer("inner", &mut inner),
1831            Attr::object("innerobject", &mut inner2_attrs),
1832        ];
1833        let mut attrs = [
1834            Attr::string("name", &mut name),
1835            Attr::object("value", &mut inner1_attrs),
1836        ];
1837
1838        read_object(
1839            r#"{"name":"wobble","value":{"inner":23,"innerobject":{"innerinner":123}}}"#,
1840            &mut attrs,
1841        )
1842        .unwrap();
1843        drop(attrs);
1844        assert_eq!(cstr(&name), "wobble");
1845        assert_eq!(inner, 23);
1846        assert_eq!(innerinner, 123);
1847    }
1848
1849    #[derive(Clone, Copy)]
1850    struct DevConfig {
1851        path: [u8; 32],
1852        activated: f64,
1853    }
1854
1855    impl DevConfig {
1856        const fn new() -> Self {
1857            Self {
1858                path: [0; 32],
1859                activated: 0.0,
1860            }
1861        }
1862    }
1863
1864    #[test]
1865    fn parses_structobject_array_with_callback() {
1866        let mut devices = [DevConfig::new(); 4];
1867        let mut count = 0;
1868        let mut parse_device = |s: &str, index: usize| {
1869            let dev = &mut devices[index];
1870            let mut attrs = [
1871                Attr::string("path", &mut dev.path),
1872                Attr::real("activated", &mut dev.activated),
1873            ];
1874            read_object(s, &mut attrs)
1875        };
1876        let mut attrs = [Attr::array(
1877            "devices",
1878            Array::StructObjects {
1879                maxlen: 4,
1880                count: Some(&mut count),
1881                parser: &mut parse_device,
1882            },
1883        )];
1884
1885        read_object(
1886            r#"{"devices":[{"path":"/dev/ttyUSB0","activated":1411468340},{"path":"/dev/ttyUSB1","activated":2.5}]}"#,
1887            &mut attrs,
1888        )
1889        .unwrap();
1890        drop(attrs);
1891        assert_eq!(count, 2);
1892        assert_eq!(cstr(&devices[0].path), "/dev/ttyUSB0");
1893        assert_eq!(devices[0].activated, 1411468340.0);
1894        assert_eq!(cstr(&devices[1].path), "/dev/ttyUSB1");
1895        assert_eq!(devices[1].activated, 2.5);
1896    }
1897
1898    #[test]
1899    fn empty_arrays_set_count_to_zero() {
1900        let mut ints = [42; 2];
1901        let mut count = 99;
1902        let mut arr = Array::Integers {
1903            store: &mut ints,
1904            count: Some(&mut count),
1905        };
1906
1907        read_array("[]", &mut arr).unwrap();
1908        drop(arr);
1909        assert_eq!(count, 0);
1910        assert_eq!(ints, [42, 42]);
1911    }
1912
1913    #[test]
1914    fn returned_end_skips_trailing_whitespace() {
1915        let mut flag = false;
1916        let input = "  {\"flag\":true}  next";
1917        let mut attrs = [Attr::boolean("flag", &mut flag)];
1918
1919        let end = read_object(input, &mut attrs).unwrap();
1920        drop(attrs);
1921        assert_eq!(&input[end..], "next");
1922        assert!(flag);
1923    }
1924
1925    #[test]
1926    fn rejects_array_overflow() {
1927        let mut ints = [0; 2];
1928        let mut arr = Array::Integers {
1929            store: &mut ints,
1930            count: None,
1931        };
1932
1933        let err = read_array("[1,2,3]", &mut arr).unwrap_err();
1934        assert_eq!(err, Error::SubTooLong);
1935    }
1936
1937    #[test]
1938    fn rejects_unknown_attribute_without_ignore() {
1939        let mut known = 0;
1940        let mut attrs = [Attr::integer("known", &mut known)];
1941
1942        let err = read_object(r#"{"unknown":1}"#, &mut attrs).unwrap_err();
1943        assert_eq!(err, Error::BadAttr);
1944    }
1945
1946    #[test]
1947    fn rejects_mismatched_quotedness() {
1948        let mut int_value = 0;
1949        let mut attrs = [Attr::integer("count", &mut int_value)];
1950        let err = read_object(r#"{"count":"1"}"#, &mut attrs).unwrap_err();
1951        assert_eq!(err, Error::QNonString);
1952
1953        let mut text = [0; 8];
1954        let mut attrs = [Attr::string("name", &mut text)];
1955        let err = read_object(r#"{"name":1}"#, &mut attrs).unwrap_err();
1956        assert_eq!(err, Error::NonQString);
1957    }
1958
1959    #[test]
1960    fn rejects_bad_numbers_and_range_overflow() {
1961        let mut int_value = 0;
1962        let mut attrs = [Attr::integer("count", &mut int_value)];
1963        let err = read_object(r#"{"count":2147483648}"#, &mut attrs).unwrap_err();
1964        assert_eq!(err, Error::BadNum);
1965
1966        let mut uint_value = 0;
1967        let mut attrs = [Attr::uinteger("count", &mut uint_value)];
1968        let err = read_object(r#"{"count":-1}"#, &mut attrs).unwrap_err();
1969        assert_eq!(err, Error::BadNum);
1970
1971        let mut real_value = 0.0;
1972        let mut attrs = [Attr::real("value", &mut real_value)];
1973        let err = read_object(r#"{"value":1e}"#, &mut attrs).unwrap_err();
1974        assert_eq!(err, Error::BadNum);
1975    }
1976
1977    #[test]
1978    fn rejects_bad_object_and_array_syntax() {
1979        let mut value = 0;
1980        let mut attrs = [Attr::integer("value", &mut value)];
1981        assert_eq!(read_object("", &mut attrs).unwrap_err(), Error::Empty);
1982        assert_eq!(read_object("[]", &mut attrs).unwrap_err(), Error::ObStart);
1983        assert_eq!(
1984            read_object("{value:1}", &mut attrs).unwrap_err(),
1985            Error::AttrStart
1986        );
1987        assert_eq!(
1988            read_object(r#"{"value":1 junk}"#, &mut attrs).unwrap_err(),
1989            Error::BadTrail
1990        );
1991
1992        let mut arr = Array::Integers {
1993            store: &mut [0; 2],
1994            count: None,
1995        };
1996        assert_eq!(read_array("{}", &mut arr).unwrap_err(), Error::ArrayStart);
1997        assert_eq!(
1998            read_array("[1 2]", &mut arr).unwrap_err(),
1999            Error::BadSubTrail
2000        );
2001    }
2002
2003    #[test]
2004    fn rejects_expected_array_or_object_when_missing() {
2005        let mut ints = [0; 2];
2006        let mut attrs = [Attr::array(
2007            "arr",
2008            Array::Integers {
2009                store: &mut ints,
2010                count: None,
2011            },
2012        )];
2013        assert_eq!(
2014            read_object(r#"{"arr":1}"#, &mut attrs).unwrap_err(),
2015            Error::NoBrak
2016        );
2017
2018        let mut value = 0;
2019        let mut child = [Attr::integer("value", &mut value)];
2020        let mut attrs = [Attr::object("child", &mut child)];
2021        assert_eq!(
2022            read_object(r#"{"child":1}"#, &mut attrs).unwrap_err(),
2023            Error::NoCurly
2024        );
2025    }
2026
2027    #[test]
2028    fn rejects_unexpected_array_or_object_values() {
2029        let mut value = 0;
2030        let mut attrs = [Attr::integer("value", &mut value)];
2031        assert_eq!(
2032            read_object(r#"{"value":[1]}"#, &mut attrs).unwrap_err(),
2033            Error::NoArray
2034        );
2035        assert_eq!(
2036            read_object(r#"{"value":{"x":1}}"#, &mut attrs).unwrap_err(),
2037            Error::NoArray
2038        );
2039    }
2040
2041    #[test]
2042    fn rejects_too_long_attribute_name() {
2043        let mut value = 0;
2044        let mut attrs = [Attr::integer("value", &mut value)];
2045        let err = read_object(r#"{"abcdefghijklmnopqrstuvwxyzabcdef":1}"#, &mut attrs).unwrap_err();
2046        assert_eq!(err, Error::AttrLen);
2047    }
2048
2049    #[test]
2050    fn rejects_invalid_string_escape() {
2051        let mut text = [0; 8];
2052        let mut attrs = [Attr::string("text", &mut text)];
2053
2054        let err = read_object(r#"{"text":"\u12x4"}"#, &mut attrs).unwrap_err();
2055        assert_eq!(err, Error::BadString);
2056    }
2057
2058    #[test]
2059    fn rejects_parallel_object_arrays_with_string_fields_after_first_element() {
2060        let mut names = [0; 16];
2061        let mut subattrs = [Attr::string("name", &mut names)];
2062        let mut attrs = [Attr::array(
2063            "items",
2064            Array::Objects {
2065                attrs: &mut subattrs,
2066                maxlen: 2,
2067                count: None,
2068            },
2069        )];
2070
2071        let err =
2072            read_object(r#"{"items":[{"name":"one"},{"name":"two"}]}"#, &mut attrs).unwrap_err();
2073        assert_eq!(err, Error::NoParStr);
2074    }
2075}