1use crate::deserialize::error::{DeserializeError as Error, DeserializeErrorKind as ErrorKind};
7use aws_smithy_types::Number;
8use ErrorKind::*;
9
10pub mod error;
11pub mod token;
12
13pub use token::{EscapeError, EscapedStr, Offset, Token};
14
15pub fn json_token_iter(input: &[u8]) -> JsonTokenIterator<'_> {
29 JsonTokenIterator {
30 input,
31 index: 0,
32 state_stack: vec![State::Initial],
33 }
34}
35
36#[derive(Copy, Clone, Debug, Eq, PartialEq)]
38enum State {
39 Initial,
41 ArrayFirstValueOrEnd,
43 ArrayNextValueOrEnd,
45 ObjectFirstKeyOrEnd,
47 ObjectNextKeyOrEnd,
49 ObjectFieldValue,
51}
52
53pub struct JsonTokenIterator<'a> {
56 input: &'a [u8],
57 index: usize,
58 state_stack: Vec<State>,
59}
60
61impl<'a> JsonTokenIterator<'a> {
62 fn peek_byte(&self) -> Option<u8> {
64 if self.index >= self.input.len() {
65 None
66 } else {
67 Some(self.input[self.index])
68 }
69 }
70
71 fn peek_expect(&self) -> Result<u8, Error> {
74 self.peek_byte().ok_or_else(|| self.error(UnexpectedEos))
75 }
76
77 fn advance(&mut self) {
79 if self.index < self.input.len() {
80 self.index += 1;
81 }
82 }
83
84 fn next_byte(&mut self) -> Option<u8> {
86 let next = self.peek_byte();
87 self.advance();
88 next
89 }
90
91 fn next_expect(&mut self) -> Result<u8, Error> {
94 self.next_byte().ok_or_else(|| self.error(UnexpectedEos))
95 }
96
97 fn error_at(&self, offset: usize, kind: ErrorKind) -> Error {
99 Error::new(kind, Some(offset))
100 }
101
102 fn error(&self, kind: ErrorKind) -> Error {
104 self.error_at(self.index, kind)
105 }
106
107 fn discard_whitespace(&mut self) {
109 while let Some(byte) = self.peek_byte() {
110 match byte {
111 b' ' | b'\t' | b'\r' | b'\n' => {
112 self.advance();
113 }
114 _ => break,
115 }
116 }
117 }
118
119 fn state(&self) -> State {
121 self.state_stack[self.state_stack.len() - 1]
122 }
123
124 fn replace_state(&mut self, state: State) {
126 self.state_stack.pop();
127 self.state_stack.push(state);
128 }
129
130 fn offset(&self) -> Offset {
132 Offset(self.index)
133 }
134
135 fn start_object(&mut self) -> Token<'a> {
137 let offset = self.offset();
138 let byte = self.next_byte();
139 debug_assert_eq!(byte, Some(b'{'));
140 self.state_stack.push(State::ObjectFirstKeyOrEnd);
141 Token::StartObject { offset }
142 }
143
144 fn end_object(&mut self) -> Token<'a> {
146 let offset = self.offset();
147 let (byte, state) = (self.next_byte(), self.state_stack.pop());
148 debug_assert_eq!(byte, Some(b'}'));
149 debug_assert!(
150 state == Some(State::ObjectFirstKeyOrEnd) || state == Some(State::ObjectNextKeyOrEnd)
151 );
152 Token::EndObject { offset }
153 }
154
155 fn start_array(&mut self) -> Token<'a> {
157 let offset = self.offset();
158 let byte = self.next_byte();
159 debug_assert_eq!(byte, Some(b'['));
160 self.state_stack.push(State::ArrayFirstValueOrEnd);
161 Token::StartArray { offset }
162 }
163
164 fn end_array(&mut self) -> Token<'a> {
166 let offset = self.offset();
167 let (byte, state) = (self.next_byte(), self.state_stack.pop());
168 debug_assert_eq!(byte, Some(b']'));
169 debug_assert!(
170 state == Some(State::ArrayFirstValueOrEnd) || state == Some(State::ArrayNextValueOrEnd)
171 );
172 Token::EndArray { offset }
173 }
174
175 fn read_string(&mut self) -> Result<&'a str, Error> {
177 let quote_byte = self.next_byte();
179 debug_assert_eq!(quote_byte, Some(b'\"'));
180
181 let start = self.index;
183 loop {
184 match self.peek_expect()? {
185 b'"' => {
186 let value = std::str::from_utf8(&self.input[start..self.index])
187 .map_err(|_| self.error(InvalidUtf8))?;
188 self.advance();
189 return Ok(value);
190 }
191 b'\\' => match self.next_expect()? {
192 b'\\' | b'/' | b'"' | b'b' | b'f' | b'n' | b'r' | b't' => self.advance(),
193 b'u' => {
194 if self.index + 4 > self.input.len() {
195 return Err(self.error_at(self.input.len(), UnexpectedEos));
196 }
197 self.index += 4;
198 }
199 byte => return Err(self.error(InvalidEscape(byte.into()))),
200 },
201 byte @ 0x00..=0x1F => return Err(self.error(UnexpectedControlCharacter(byte))),
202 _ => self.advance(),
203 }
204 }
205 }
206
207 fn expect_literal(&mut self, expected: &[u8]) -> Result<(), Error> {
209 let (start, end) = (self.index, self.index + expected.len());
210 if end > self.input.len() {
211 return Err(self.error_at(self.input.len(), UnexpectedEos));
212 }
213 if expected != &self.input[start..end] {
214 return Err(self.error_at(
215 start,
216 ExpectedLiteral(std::str::from_utf8(expected).unwrap().into()),
217 ));
218 }
219 self.index = end;
220 Ok(())
221 }
222
223 fn expect_null(&mut self) -> Result<Token<'a>, Error> {
225 let offset = self.offset();
226 self.expect_literal(b"null")?;
227 Ok(Token::ValueNull { offset })
228 }
229
230 fn expect_bool(&mut self) -> Result<Token<'a>, Error> {
232 let offset = self.offset();
233 match self.peek_expect()? {
234 b't' => {
235 self.expect_literal(b"true")?;
236 Ok(Token::ValueBool {
237 offset,
238 value: true,
239 })
240 }
241 b'f' => {
242 self.expect_literal(b"false")?;
243 Ok(Token::ValueBool {
244 offset,
245 value: false,
246 })
247 }
248 _ => unreachable!(
249 "this function must only be called when the next character is 't' or 'f'"
250 ),
251 }
252 }
253
254 fn skip_exponent(&mut self) {
256 self.advance();
257 match self.peek_byte() {
258 Some(b'-') => self.advance(),
259 Some(b'+') => self.advance(),
260 _ => {}
261 }
262 while let Some(b'0'..=b'9') = self.peek_byte() {
263 self.advance();
264 }
265 }
266
267 fn skip_decimal(&mut self) {
269 self.advance();
270 while let Some(byte) = self.peek_byte() {
271 match byte {
272 b'0'..=b'9' => self.advance(),
273 b'e' | b'E' => self.skip_exponent(),
274 _ => break,
275 }
276 }
277 }
278
279 fn scan_number(&mut self) -> (usize, usize, bool, bool) {
286 let start_index = self.index;
287 let negative = if self.peek_byte() == Some(b'-') {
288 self.advance();
289 true
290 } else {
291 false
292 };
293 let mut floating = false;
294 while let Some(byte) = self.peek_byte() {
295 match byte {
296 b'0'..=b'9' => self.advance(),
297 b'.' => {
298 floating = true;
299 self.skip_decimal();
300 }
301 b'e' | b'E' => {
302 floating = true;
303 self.skip_exponent();
304 }
305 _ => break,
306 }
307 }
308 (start_index, self.index, negative, floating)
309 }
310
311 fn expect_number(&mut self) -> Result<Token<'a>, Error> {
313 let offset = self.offset();
314 let (start, end, negative, floating) = self.scan_number();
315 let number_slice = &self.input[start..end];
316
317 debug_assert!(std::str::from_utf8(number_slice).is_ok());
319 let number_str = unsafe { std::str::from_utf8_unchecked(number_slice) };
320
321 use std::str::FromStr;
322 Ok(Token::ValueNumber {
323 offset,
324 value: if floating {
325 Number::Float(
326 f64::from_str(number_str)
327 .map_err(|_| self.error_at(start, InvalidNumber))
328 .and_then(|f| {
329 must_be_finite(f).map_err(|_| self.error_at(start, InvalidNumber))
330 })?,
331 )
332 } else if negative {
333 let positive = u64::from_str(&number_str[1..])
335 .map_err(|_| self.error_at(start, InvalidNumber))?;
336 let negative = positive.wrapping_neg() as i64;
337 if negative > 0 {
338 Number::Float(-(positive as f64))
339 } else {
340 Number::NegInt(negative)
341 }
342 } else {
343 Number::PosInt(
344 u64::from_str(number_str).map_err(|_| self.error_at(start, InvalidNumber))?,
345 )
346 },
347 })
348 }
349
350 fn read_value(&mut self) -> Result<Token<'a>, Error> {
354 self.discard_whitespace();
355 let offset = self.offset();
356 match self.peek_expect()? {
357 b'{' => Ok(self.start_object()),
358 b'[' => Ok(self.start_array()),
359 b'"' => self.read_string().map(|s| Token::ValueString {
360 offset,
361 value: EscapedStr::new(s),
362 }),
363 byte => {
364 let value = match byte {
365 b'n' => self.expect_null(),
366 b't' | b'f' => self.expect_bool(),
367 b'-' | (b'0'..=b'9') => self.expect_number(),
368 byte => Err(self.error(UnexpectedToken(
369 byte.into(),
370 "'{', '[', '\"', 'null', 'true', 'false', <number>",
371 ))),
372 }?;
373 if let Some(byte) = self.peek_byte() {
375 match byte {
376 b' ' | b'\t' | b'\r' | b'\n' | b'}' | b']' | b',' => {}
377 _ => {
378 return Err(self.error(UnexpectedToken(
379 byte.into(),
380 "<whitespace>, '}', ']', ','",
381 )))
382 }
383 }
384 }
385 Ok(value)
386 }
387 }
388 }
389
390 fn state_array_first_value_or_end(&mut self) -> Result<Token<'a>, Error> {
392 match self.peek_expect()? {
393 b']' => Ok(self.end_array()),
394 _ => {
395 self.replace_state(State::ArrayNextValueOrEnd);
396 self.read_value()
397 }
398 }
399 }
400
401 fn state_array_next_value_or_end(&mut self) -> Result<Token<'a>, Error> {
403 match self.peek_expect()? {
404 b']' => Ok(self.end_array()),
405 b',' => {
406 self.advance();
407 self.read_value()
408 }
409 byte => Err(self.error(UnexpectedToken(byte.into(), "']', ','"))),
410 }
411 }
412
413 fn object_key(&mut self) -> Result<Token<'a>, Error> {
415 let offset = self.offset();
416 match self.peek_expect()? {
417 b'"' => {
418 self.replace_state(State::ObjectFieldValue);
419 self.read_string().map(|s| Token::ObjectKey {
420 offset,
421 key: EscapedStr::new(s),
422 })
423 }
424 byte => Err(self.error(UnexpectedToken(byte.into(), "'\"'"))),
425 }
426 }
427
428 fn state_object_first_key_or_end(&mut self) -> Result<Token<'a>, Error> {
430 match self.peek_expect()? {
431 b'}' => Ok(self.end_object()),
432 _ => self.object_key(),
433 }
434 }
435
436 fn state_object_next_key_or_end(&mut self) -> Result<Token<'a>, Error> {
438 match self.peek_expect()? {
439 b'}' => Ok(self.end_object()),
440 b',' => {
441 self.advance();
442 self.discard_whitespace();
443 self.object_key()
444 }
445 byte => Err(self.error(UnexpectedToken(byte.into(), "'}', ','"))),
446 }
447 }
448
449 fn state_object_field_value(&mut self) -> Result<Token<'a>, Error> {
451 match self.peek_expect()? {
452 b':' => {
453 self.advance();
454 self.replace_state(State::ObjectNextKeyOrEnd);
455 self.read_value()
456 }
457 byte => Err(self.error(UnexpectedToken(byte.into(), "':'"))),
458 }
459 }
460}
461
462impl<'a> Iterator for JsonTokenIterator<'a> {
463 type Item = Result<Token<'a>, Error>;
464
465 fn next(&mut self) -> Option<Self::Item> {
466 debug_assert!(self.index <= self.input.len());
467 if self.index == self.input.len() {
468 return None;
469 }
470
471 self.discard_whitespace();
472 let result = match self.state() {
473 State::Initial => self.peek_byte().map(|_| self.read_value()),
474 State::ArrayFirstValueOrEnd => Some(self.state_array_first_value_or_end()),
475 State::ArrayNextValueOrEnd => Some(self.state_array_next_value_or_end()),
476 State::ObjectFirstKeyOrEnd => Some(self.state_object_first_key_or_end()),
477 State::ObjectNextKeyOrEnd => Some(self.state_object_next_key_or_end()),
478 State::ObjectFieldValue => Some(self.state_object_field_value()),
479 };
480 if result.as_ref().map(|r| r.is_err()).unwrap_or(false) {
482 self.index = self.input.len();
483 }
484 result
485 }
486}
487
488fn must_be_finite(f: f64) -> Result<f64, ()> {
489 if f.is_finite() {
490 Ok(f)
491 } else {
492 Err(())
493 }
494}
495
496fn must_not_be_finite(f: f64) -> Result<f64, ()> {
497 if !f.is_finite() {
498 Ok(f)
499 } else {
500 Err(())
501 }
502}
503
504#[cfg(test)]
505mod tests {
506 use crate::deserialize::error::{DeserializeError as Error, DeserializeErrorKind as ErrorKind};
507 use crate::deserialize::token::test::{
508 end_array, end_object, object_key, start_array, start_object, value_bool, value_null,
509 value_number, value_string,
510 };
511 use crate::deserialize::{json_token_iter, EscapedStr, Token};
512 use aws_smithy_types::Number;
513 use proptest::prelude::*;
514
515 #[track_caller]
516 fn expect_token(
517 expected: Option<Result<Token<'_>, Error>>,
518 actual: Option<Result<Token<'_>, Error>>,
519 ) {
520 let (expected, actual) = (
521 expected.transpose().expect("err in expected"),
522 actual.transpose().expect("err in actual"),
523 );
524 assert_eq!(expected, actual);
525 }
526
527 macro_rules! expect_err {
528 ($kind:pat, $offset:expr, $value:expr) => {
529 let err: Error = $value.transpose().err().expect("expected error");
530 assert!(matches!(err.kind, $kind));
531 assert_eq!($offset, err.offset);
532 };
533 }
534
535 #[test]
536 fn test_empty() {
537 assert!(json_token_iter(b"").next().is_none());
538 assert!(json_token_iter(b" ").next().is_none());
539 assert!(json_token_iter(b"\t").next().is_none());
540 }
541
542 #[test]
543 fn test_empty_string() {
544 let mut iter = json_token_iter(b"\"\"");
545 expect_token(value_string(0, ""), iter.next());
546 expect_token(None, iter.next());
547
548 let mut iter = json_token_iter(b" \r\n\t \"\" ");
549 expect_token(value_string(5, ""), iter.next());
550 expect_token(None, iter.next());
551 }
552
553 #[test]
554 fn test_empty_array() {
555 let mut iter = json_token_iter(b"[]");
556 expect_token(start_array(0), iter.next());
557 expect_token(end_array(1), iter.next());
558 expect_token(None, iter.next());
559 }
560
561 #[test]
562 fn test_empty_object() {
563 let mut iter = json_token_iter(b"{}");
564 expect_token(start_object(0), iter.next());
565 expect_token(end_object(1), iter.next());
566 expect_token(None, iter.next());
567 }
568
569 #[test]
570 fn test_null() {
571 expect_token(value_null(1), json_token_iter(b" null ").next());
572
573 let mut iter = json_token_iter(b"[null, null,null]");
574 expect_token(start_array(0), iter.next());
575 expect_token(value_null(1), iter.next());
576 expect_token(value_null(7), iter.next());
577 expect_token(value_null(12), iter.next());
578 expect_token(end_array(16), iter.next());
579 expect_token(None, iter.next());
580
581 assert!(json_token_iter(b"n").next().unwrap().is_err());
582 assert!(json_token_iter(b"nul").next().unwrap().is_err());
583 assert!(json_token_iter(b"nulll").next().unwrap().is_err());
584 }
585
586 #[test]
587 fn test_bools() {
588 assert!(json_token_iter(b"tru").next().unwrap().is_err());
589 assert!(json_token_iter(b"truee").next().unwrap().is_err());
590 assert!(json_token_iter(b"f").next().unwrap().is_err());
591 assert!(json_token_iter(b"falsee").next().unwrap().is_err());
592 expect_token(value_bool(1, true), json_token_iter(b" true ").next());
593 expect_token(value_bool(0, false), json_token_iter(b"false").next());
594
595 let mut iter = json_token_iter(b"[true,false]");
596 expect_token(start_array(0), iter.next());
597 expect_token(value_bool(1, true), iter.next());
598 expect_token(value_bool(6, false), iter.next());
599 expect_token(end_array(11), iter.next());
600 expect_token(None, iter.next());
601 }
602
603 proptest! {
604 #[test]
605 fn string_prop_test(input in ".*") {
606 let json: String = serde_json::to_string(&input).unwrap();
607 let mut iter = json_token_iter(json.as_bytes());
608 expect_token(value_string(0, &json[1..(json.len() - 1)]), iter.next());
609 expect_token(None, iter.next());
610 }
611
612 #[test]
613 fn integer_prop_test(input: i64) {
614 let json = serde_json::to_string(&input).unwrap();
615 let mut iter = json_token_iter(json.as_bytes());
616 let expected = if input < 0 {
617 Number::NegInt(input)
618 } else {
619 Number::PosInt(input as u64)
620 };
621 expect_token(value_number(0, expected), iter.next());
622 expect_token(None, iter.next());
623 }
624
625 #[test]
626 fn float_prop_test(input: f64) {
627 let json = serde_json::to_string(&input).unwrap();
628 let mut iter = json_token_iter(json.as_bytes());
629 expect_token(value_number(0, Number::Float(input)), iter.next());
630 expect_token(None, iter.next());
631 }
632 }
633
634 #[test]
635 fn valid_numbers() {
636 let expect = |number, input| {
637 expect_token(value_number(0, number), json_token_iter(input).next());
638 };
639 expect(Number::Float(0.0), b"0.");
640 expect(Number::Float(0.0), b"0e0");
641 expect(Number::Float(0.0), b"0E0");
642 expect(Number::Float(10.0), b"1E1");
643 expect(Number::Float(10.0), b"1E+1");
644 expect(Number::Float(100.0), b"1e+2");
645
646 expect(Number::NegInt(-50000), b"-50000");
647 expect(
648 Number::Float(-18446744073709551615.0),
649 b"-18446744073709551615",
650 );
651 }
652
653 #[test]
656 fn invalid_numbers_we_are_intentionally_accepting() {
657 let expect = |number, input| {
658 expect_token(value_number(0, number), json_token_iter(input).next());
659 };
660
661 expect(Number::NegInt(-1), b"-01");
662 expect(Number::Float(-2.0), b"-2.");
663 expect(Number::Float(0.0), b"0.e1");
664 expect(Number::Float(0.002), b"2.e-3");
665 expect(Number::Float(2000.0), b"2.e3");
666 expect(Number::NegInt(-12), b"-012");
667 expect(Number::Float(-0.123), b"-.123");
668 expect(Number::Float(1.0), b"1.");
669 expect(Number::PosInt(12), b"012");
670 }
671
672 #[test]
673 fn invalid_numbers() {
674 macro_rules! unexpected_token {
675 ($input:expr, $token:pat, $offset:expr, $msg:pat) => {
676 let tokens: Vec<Result<Token<'_>, Error>> = json_token_iter($input).collect();
677 assert_eq!(1, tokens.len());
678 expect_err!(
679 ErrorKind::UnexpectedToken($token, $msg),
680 Some($offset),
681 tokens.into_iter().next()
682 );
683 };
684 }
685
686 let invalid_number = |input, offset| {
687 let tokens: Vec<Result<Token<'_>, Error>> = json_token_iter(input).collect();
688 assert_eq!(1, tokens.len());
689 expect_err!(
690 ErrorKind::InvalidNumber,
691 Some(offset),
692 tokens.into_iter().next()
693 );
694 };
695
696 unexpected_token!(
697 b".",
698 '.',
699 0,
700 "'{', '[', '\"', 'null', 'true', 'false', <number>"
701 );
702 unexpected_token!(
703 b".0",
704 '.',
705 0,
706 "'{', '[', '\"', 'null', 'true', 'false', <number>"
707 );
708 unexpected_token!(b"0-05", '-', 1, "<whitespace>, '}', ']', ','");
709 unexpected_token!(b"0x05", 'x', 1, "<whitespace>, '}', ']', ','");
710 unexpected_token!(b"123.invalid", 'i', 4, "<whitespace>, '}', ']', ','");
711 unexpected_token!(b"123invalid", 'i', 3, "<whitespace>, '}', ']', ','");
712 unexpected_token!(
713 b"asdf",
714 'a',
715 0,
716 "'{', '[', '\"', 'null', 'true', 'false', <number>"
717 );
718
719 invalid_number(b"-a", 0);
720 invalid_number(b"1e", 0);
721 invalid_number(b"1e-", 0);
722
723 invalid_number(b"123.0Einvalid", 0);
725 }
726
727 #[test]
728 fn test_unclosed_array() {
729 let mut iter = json_token_iter(br#" [null "#);
730 expect_token(start_array(1), iter.next());
731 expect_token(value_null(2), iter.next());
732 expect_err!(ErrorKind::UnexpectedEos, Some(7), iter.next());
733 }
734
735 #[test]
736 fn test_array_with_items() {
737 let mut iter = json_token_iter(b"[[], {}, \"test\"]");
738 expect_token(start_array(0), iter.next());
739 expect_token(start_array(1), iter.next());
740 expect_token(end_array(2), iter.next());
741 expect_token(start_object(5), iter.next());
742 expect_token(end_object(6), iter.next());
743 expect_token(value_string(9, "test"), iter.next());
744 expect_token(end_array(15), iter.next());
745 expect_token(None, iter.next());
746 }
747
748 #[test]
749 fn test_object_with_items() {
750 let mut tokens = json_token_iter(
751 br#"{ "some_int": 5,
752 "some_float": 5.2,
753 "some_negative": -5,
754 "some_negative_float": -2.4,
755 "some_string": "test",
756 "some_struct": { "nested": "asdf" },
757 "some_array": ["one", "two"] }"#,
758 );
759 expect_token(start_object(0), tokens.next());
760 expect_token(object_key(2, "some_int"), tokens.next());
761 expect_token(value_number(14, Number::PosInt(5)), tokens.next());
762 expect_token(object_key(35, "some_float"), tokens.next());
763 expect_token(value_number(49, Number::Float(5.2)), tokens.next());
764 expect_token(object_key(72, "some_negative"), tokens.next());
765 expect_token(value_number(89, Number::NegInt(-5)), tokens.next());
766 expect_token(object_key(111, "some_negative_float"), tokens.next());
767 expect_token(value_number(134, Number::Float(-2.4)), tokens.next());
768 expect_token(object_key(158, "some_string"), tokens.next());
769 expect_token(value_string(173, "test"), tokens.next());
770 expect_token(object_key(199, "some_struct"), tokens.next());
771 expect_token(start_object(214), tokens.next());
772 expect_token(object_key(216, "nested"), tokens.next());
773 expect_token(value_string(226, "asdf"), tokens.next());
774 expect_token(end_object(233), tokens.next());
775 expect_token(object_key(254, "some_array"), tokens.next());
776 expect_token(start_array(268), tokens.next());
777 expect_token(value_string(269, "one"), tokens.next());
778 expect_token(value_string(276, "two"), tokens.next());
779 expect_token(end_array(281), tokens.next());
780 expect_token(end_object(283), tokens.next());
781 expect_token(None, tokens.next());
782 }
783
784 #[test]
785 fn test_object_trailing_comma() {
786 let mut iter = json_token_iter(br#" { "test": "trailing", } "#);
787 expect_token(start_object(1), iter.next());
788 expect_token(object_key(3, "test"), iter.next());
789 expect_token(value_string(11, "trailing"), iter.next());
790 expect_err!(
791 ErrorKind::UnexpectedToken('}', "'\"'"),
792 Some(23),
793 iter.next()
794 );
795 assert!(iter.next().is_none());
796 }
797
798 #[test]
799 fn test_object_no_colon() {
800 let mut iter = json_token_iter(br#" {"test" "#);
801 expect_token(start_object(1), iter.next());
802 expect_token(object_key(2, "test"), iter.next());
803 expect_err!(ErrorKind::UnexpectedEos, Some(9), iter.next());
804 expect_token(None, iter.next());
805 }
806
807 #[test]
808 fn unescaped_ctrl_characters() {
809 assert!(json_token_iter(b"\"test\x00test\"")
810 .next()
811 .unwrap()
812 .is_err());
813 assert!(json_token_iter(b"\"test\ntest\"").next().unwrap().is_err());
814 assert!(json_token_iter(b"\"test\ttest\"").next().unwrap().is_err());
815 }
816
817 #[test]
818 fn escaped_str() {
819 let escaped = EscapedStr::new("foo\\nbar");
820 assert_eq!("foo\\nbar", escaped.as_escaped_str());
821 assert_eq!("foo\nbar", escaped.to_unescaped().unwrap());
822 }
823}