Skip to main content

fixed_json/
parser.rs

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