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}