facet_json/
deserialize.rs

1use core::num::{
2    NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroIsize, NonZeroU8, NonZeroU16, NonZeroU32,
3    NonZeroU64, NonZeroUsize,
4};
5
6#[cfg(feature = "rich-diagnostics")]
7use ariadne::{Color, Config, IndexType, Label, Report, ReportKind, Source};
8use facet_core::{Def, Facet, FieldAttribute, ScalarAffinity};
9use facet_reflect::{HeapValue, Wip};
10use log::trace;
11
12use alloc::format;
13use alloc::string::{String, ToString};
14use alloc::vec::Vec;
15use owo_colors::OwoColorize;
16
17/// A JSON parse error, with context. Never would've guessed huh.
18#[derive(Debug)]
19pub struct JsonParseErrorWithContext<'input> {
20    #[cfg_attr(not(feature = "rich-diagnostics"), allow(dead_code))]
21    input: &'input [u8],
22    pos: usize,
23    kind: JsonErrorKind,
24    path: String,
25}
26
27impl<'input> JsonParseErrorWithContext<'input> {
28    /// Creates a new `JsonParseErrorWithContext`.
29    ///
30    /// # Arguments
31    ///
32    /// * `kind` - The kind of JSON error encountered.
33    /// * `input` - The original input being parsed.
34    /// * `pos` - The position in the input where the error occurred.
35    pub fn new(kind: JsonErrorKind, input: &'input [u8], pos: usize, path: String) -> Self {
36        Self {
37            input,
38            pos,
39            kind,
40            path,
41        }
42    }
43
44    /// Returns a human-readable error message for this JSON error.
45    pub fn message(&self) -> String {
46        match &self.kind {
47            JsonErrorKind::UnexpectedEof => "Unexpected end of file".to_string(),
48            JsonErrorKind::UnexpectedCharacter(c) => format!("Unexpected character: '{}'", c),
49            JsonErrorKind::NumberOutOfRange(n) => format!("Number out of range: {}", n),
50            JsonErrorKind::StringAsNumber(s) => format!("Expected a string but got number: {}", s),
51            JsonErrorKind::UnknownField(f) => format!("Unknown field: {}", f),
52            JsonErrorKind::InvalidUtf8(e) => format!("Invalid UTF-8 encoding: {}", e),
53        }
54    }
55}
56
57/// An error kind for JSON parsing.
58#[derive(Debug)]
59pub enum JsonErrorKind {
60    /// The input ended unexpectedly while parsing JSON.
61    UnexpectedEof,
62    /// An unexpected character was encountered in the input.
63    UnexpectedCharacter(char),
64    /// A number is out of range.
65    NumberOutOfRange(f64),
66    /// An unexpected String was encountered in the input.
67    StringAsNumber(String),
68    /// An unexpected field name was encountered in the input.
69    UnknownField(String),
70    /// A string that could not be built into valid UTF-8 Unicode
71    InvalidUtf8(String),
72}
73
74#[cfg(not(feature = "rich-diagnostics"))]
75impl core::fmt::Display for JsonParseErrorWithContext<'_> {
76    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77        write!(
78            f,
79            "{} at byte {} in path {}",
80            self.message(),
81            self.pos,
82            self.path
83        )
84    }
85}
86
87#[cfg(feature = "rich-diagnostics")]
88impl core::fmt::Display for JsonParseErrorWithContext<'_> {
89    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
90        let Ok(input_str) = core::str::from_utf8(self.input) else {
91            return write!(f, "(JSON input was invalid UTF-8)");
92        };
93
94        let source_id = "json";
95
96        let (span_start, span_end) = match &self.kind {
97            JsonErrorKind::StringAsNumber(s) => (self.pos - s.len(), self.pos),
98            JsonErrorKind::UnknownField(f) => (self.pos - f.len() - 1, self.pos - 1),
99            _ => {
100                let span_end = if self.pos < self.input.len() {
101                    self.pos + 1
102                } else {
103                    self.input.len()
104                };
105                (self.pos, span_end)
106            }
107        };
108
109        let mut report = Report::build(ReportKind::Error, (source_id, span_start..span_end))
110            .with_message(format!("Error at {}", self.path.yellow()))
111            .with_config(Config::new().with_index_type(IndexType::Byte));
112
113        let label = Label::new((source_id, span_start..span_end))
114            .with_message(self.message())
115            .with_color(Color::Red);
116
117        report = report.with_label(label);
118
119        let source = Source::from(input_str);
120
121        let mut writer = Vec::new();
122        let cache = (source_id, &source);
123
124        if report.finish().write(cache, &mut writer).is_err() {
125            return write!(f, "Error formatting with ariadne");
126        }
127
128        if let Ok(output) = String::from_utf8(writer) {
129            write!(f, "{}", output)
130        } else {
131            write!(f, "Error converting ariadne output to string")
132        }
133    }
134}
135
136impl core::error::Error for JsonParseErrorWithContext<'_> {}
137
138/// Deserializes a JSON string into a value of type `T` that implements `Facet`.
139///
140/// This function takes a JSON string representation and converts it into a Rust
141/// value of the specified type `T`. The type must implement the `Facet` trait
142/// to provide the necessary type information for deserialization.
143pub fn from_str<T: Facet>(json: &str) -> Result<T, JsonParseErrorWithContext<'_>> {
144    from_slice(json.as_bytes())
145}
146
147/// Deserialize JSON from a slice
148///
149/// # Arguments
150///
151/// * `json` - A slice of bytes representing the JSON input.
152///
153/// # Returns
154///
155/// A result containing the deserialized value of type `T` or a `JsonParseErrorWithContext`.
156pub fn from_slice<T: Facet>(json: &[u8]) -> Result<T, JsonParseErrorWithContext<'_>> {
157    let wip = Wip::alloc::<T>();
158    let heap_value = from_slice_wip(wip, json)?;
159    Ok(heap_value.materialize::<T>().unwrap())
160}
161
162/// Deserialize a JSON string into a Wip object.
163///
164/// # Arguments
165///
166/// * `wip` - A mutable Wip object to deserialize into.
167/// * `input` - A byte slice representing the JSON input.
168///
169/// # Returns
170///
171/// A result containing the updated `Wip` or a `JsonParseErrorWithContext`.
172pub fn from_slice_wip<'input, 'a>(
173    mut wip: Wip<'a>,
174    input: &'input [u8],
175) -> Result<HeapValue<'a>, JsonParseErrorWithContext<'input>> {
176    let mut pos = 0;
177
178    macro_rules! err {
179        ($kind:expr) => {
180            Err(JsonParseErrorWithContext::new(
181                $kind,
182                input,
183                pos,
184                wip.path(),
185            ))
186        };
187    }
188    macro_rules! bail {
189        ($kind:expr) => {
190            return err!($kind)
191        };
192    }
193
194    /// Indicates why we are expecting a value in the parsing stack.
195    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
196    enum WhyValue {
197        /// At the top level of the JSON input.
198        TopLevel,
199        /// Expecting an object key.
200        ObjectKey,
201        /// Expecting an object value.
202        ObjectValue,
203        /// Expecting an array element.
204        ArrayElement,
205    }
206
207    /// Indicates the context for a comma separator in JSON (object or array).
208    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
209    enum WhyComma {
210        /// A comma in an object context.
211        Object,
212        /// A comma in an array context.
213        Array,
214    }
215
216    /// Indicates the type of separator expected (colon or comma).
217    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
218    enum Separator {
219        /// Expecting a colon separator in object key-value pairs.
220        Colon,
221        /// Expecting a comma separator (in objects or arrays).
222        Comma(WhyComma),
223    }
224
225    /// Represents the next expected token or structure while parsing.
226    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
227    enum Expect {
228        /// Expecting a value, with its reason/context.
229        Value(WhyValue),
230        /// Expecting a separator (colon or comma).
231        Separator(Separator),
232        /// We did `push_some` and now we need to pop it
233        PopOption,
234    }
235
236    let mut stack: Vec<Expect> = Vec::new();
237    stack.push(Expect::Value(WhyValue::TopLevel));
238
239    loop {
240        // skip over whitespace
241        while let Some(c) = input.get(pos).copied() {
242            match c {
243                b' ' | b'\t' | b'\n' | b'\r' => {
244                    pos += 1;
245                }
246                _ => break,
247            }
248        }
249
250        let frame_count = wip.frames_count();
251        let expect = match stack.pop() {
252            Some(expect) => expect,
253            None => {
254                if frame_count == 1 {
255                    return Ok(wip.build().unwrap());
256                } else {
257                    bail!(JsonErrorKind::UnexpectedEof);
258                }
259            }
260        };
261        trace!("[{frame_count}] Expecting {expect:?}");
262
263        let Some(c) = input.get(pos).copied() else {
264            bail!(JsonErrorKind::UnexpectedEof);
265        };
266
267        match expect {
268            Expect::PopOption => {
269                // that's all, carry on
270                trace!("Popping option");
271                wip = wip.pop().unwrap();
272            }
273            Expect::Value(why) => {
274                if let Def::Option(_) = wip.shape().def {
275                    wip = wip.push_some().unwrap();
276                    stack.push(Expect::PopOption);
277                }
278
279                match c {
280                    b'{' => {
281                        pos += 1;
282                        let Some(c) = input.get(pos).copied() else {
283                            bail!(JsonErrorKind::UnexpectedEof);
284                        };
285                        match c {
286                            b'}' => {
287                                pos += 1;
288                                if frame_count > 1 {
289                                    // just finished reading a value I guess
290                                    wip = wip.pop().unwrap();
291                                }
292                            }
293                            _ => {
294                                // okay, next we expect a "key: value"
295                                stack.push(Expect::Separator(Separator::Comma(WhyComma::Object)));
296                                stack.push(Expect::Value(WhyValue::ObjectValue));
297                                stack.push(Expect::Separator(Separator::Colon));
298                                stack.push(Expect::Value(WhyValue::ObjectKey));
299                            }
300                        }
301                    }
302                    b'[' => {
303                        pos += 1;
304                        let Some(c) = input.get(pos).copied() else {
305                            bail!(JsonErrorKind::UnexpectedEof);
306                        };
307
308                        wip = wip.begin_pushback().unwrap();
309                        match c {
310                            b']' => {
311                                // an array just closed, somewhere
312                                pos += 1;
313                            }
314                            _ => {
315                                // okay, next we expect an item and a separator (or the end of the array)
316                                stack.push(Expect::Separator(Separator::Comma(WhyComma::Array)));
317                                stack.push(Expect::Value(WhyValue::ArrayElement));
318                                wip = wip.push().unwrap();
319                            }
320                        }
321                    }
322                    b'"' => {
323                        pos += 1;
324                        // Our value is a string: collect bytes first
325                        let mut bytes = Vec::new();
326                        loop {
327                            let Some(c) = input.get(pos).copied() else {
328                                bail!(JsonErrorKind::UnexpectedEof);
329                            };
330                            match c {
331                                b'"' => {
332                                    pos += 1;
333                                    break;
334                                }
335                                b'\\' => {
336                                    // Handle escape sequences
337                                    pos += 1;
338                                    if let Some(next) = input.get(pos) {
339                                        bytes.push(*next);
340                                        pos += 1;
341                                    } else {
342                                        bail!(JsonErrorKind::UnexpectedEof);
343                                    }
344                                }
345                                _ => {
346                                    bytes.push(c);
347                                    pos += 1;
348                                }
349                            }
350                        }
351
352                        // Convert collected bytes to string at once
353                        let value = match core::str::from_utf8(&bytes) {
354                            Ok(s) => s.to_string(),
355                            Err(e) => {
356                                bail!(JsonErrorKind::InvalidUtf8(format!(
357                                    "Invalid UTF-8 sequence: {}",
358                                    e
359                                )))
360                            }
361                        };
362
363                        trace!(
364                            "Parsed string value: {:?} for shape {}",
365                            value.yellow(),
366                            wip.shape()
367                        );
368
369                        match why {
370                            WhyValue::TopLevel => {
371                                wip = wip.parse(&value).unwrap();
372                            }
373                            WhyValue::ArrayElement => {
374                                wip = wip.parse(&value).unwrap();
375                                wip = wip.pop().unwrap();
376                            }
377                            WhyValue::ObjectValue => {
378                                wip = wip.parse(&value).unwrap();
379                                wip = wip.pop().unwrap();
380                            }
381                            WhyValue::ObjectKey => {
382                                // Look for field with matching name or rename attribute
383                                let field_shape = wip.shape();
384                                if let Def::Struct(struct_def) = field_shape.def {
385                                    let field = struct_def.fields.iter().find(|f| {
386                                        // Check original name
387                                        if f.name == value {
388                                            return true;
389                                        }
390
391                                        // Check rename attribute
392                                        f.attributes.iter().any(|attr| {
393                                            if let FieldAttribute::Rename(rename) = attr {
394                                                rename == &value
395                                            } else {
396                                                false
397                                            }
398                                        })
399                                    });
400
401                                    if let Some(field) = field {
402                                        wip = wip.field_named(field.name).unwrap();
403                                    } else {
404                                        // Field not found - original or renamed
405                                        bail!(JsonErrorKind::UnknownField(value.to_string()));
406                                    }
407                                } else {
408                                    wip = wip.field_named(&value).unwrap();
409                                }
410                            }
411                        }
412                    }
413                    b'0'..=b'9' | b'-' => {
414                        pos += 1;
415                        let start = pos - 1;
416                        while let Some(c) = input.get(pos) {
417                            match c {
418                                b'0'..=b'9' | b'.' => {
419                                    pos += 1;
420                                }
421                                _ => break,
422                            }
423                        }
424                        let number = &input[start..pos];
425                        let number = core::str::from_utf8(number).unwrap();
426                        trace!("Parsed number value: {:?}", number.yellow());
427                        let number = number.parse::<f64>().unwrap();
428                        trace!("Parsed number value: {:?}", number.yellow());
429
430                        let shape = wip.shape();
431                        match shape.def {
432                            Def::Scalar(sd) => match sd.affinity {
433                                ScalarAffinity::Number(_na) => {
434                                    if shape.is_type::<u8>() {
435                                        if number >= 0.0 && number <= u8::MAX as f64 {
436                                            let value = number as u8;
437                                            wip = wip.put::<u8>(value).unwrap();
438                                        } else {
439                                            bail!(JsonErrorKind::NumberOutOfRange(number));
440                                        }
441                                    } else if shape.is_type::<u16>() {
442                                        if number >= 0.0 && number <= u16::MAX as f64 {
443                                            let value = number as u16;
444                                            wip = wip.put::<u16>(value).unwrap();
445                                        } else {
446                                            bail!(JsonErrorKind::NumberOutOfRange(number));
447                                        }
448                                    } else if shape.is_type::<u32>() {
449                                        if number >= 0.0 && number <= u32::MAX as f64 {
450                                            let value = number as u32;
451                                            wip = wip.put::<u32>(value).unwrap();
452                                        } else {
453                                            bail!(JsonErrorKind::NumberOutOfRange(number));
454                                        }
455                                    } else if shape.is_type::<u64>() {
456                                        if number >= 0.0 && number <= u64::MAX as f64 {
457                                            let value = number as u64;
458                                            wip = wip.put::<u64>(value).unwrap();
459                                        } else {
460                                            bail!(JsonErrorKind::NumberOutOfRange(number));
461                                        }
462                                    } else if shape.is_type::<i8>() {
463                                        if number >= i8::MIN as f64 && number <= i8::MAX as f64 {
464                                            let value = number as i8;
465                                            wip = wip.put::<i8>(value).unwrap();
466                                        } else {
467                                            bail!(JsonErrorKind::NumberOutOfRange(number));
468                                        }
469                                    } else if shape.is_type::<i16>() {
470                                        if number >= i16::MIN as f64 && number <= i16::MAX as f64 {
471                                            let value = number as i16;
472                                            wip = wip.put::<i16>(value).unwrap();
473                                        } else {
474                                            bail!(JsonErrorKind::NumberOutOfRange(number));
475                                        }
476                                    } else if shape.is_type::<i32>() {
477                                        if number >= i32::MIN as f64 && number <= i32::MAX as f64 {
478                                            let value = number as i32;
479                                            wip = wip.put::<i32>(value).unwrap();
480                                        } else {
481                                            bail!(JsonErrorKind::NumberOutOfRange(number));
482                                        }
483                                    } else if shape.is_type::<i64>() {
484                                        // Note: f64 might lose precision for large i64 values, but this is a common limitation.
485                                        if number >= i64::MIN as f64 && number <= i64::MAX as f64 {
486                                            let value = number as i64;
487                                            wip = wip.put::<i64>(value).unwrap();
488                                        } else {
489                                            bail!(JsonErrorKind::NumberOutOfRange(number));
490                                        }
491                                    } else if shape.is_type::<f32>() {
492                                        if number >= f32::MIN as f64 && number <= f32::MAX as f64 {
493                                            let value = number as f32;
494                                            wip = wip.put::<f32>(value).unwrap();
495                                        } else {
496                                            bail!(JsonErrorKind::NumberOutOfRange(number));
497                                        }
498                                    } else if shape.is_type::<f64>() {
499                                        wip = wip.put::<f64>(number).unwrap();
500                                    } else if shape.is_type::<NonZeroU8>() {
501                                        if number >= 1.0 && number <= u8::MAX as f64 {
502                                            let value = NonZeroU8::new(number as u8).unwrap();
503                                            wip = wip.put::<NonZeroU8>(value).unwrap();
504                                        } else {
505                                            bail!(JsonErrorKind::NumberOutOfRange(number));
506                                        }
507                                    } else if shape.is_type::<NonZeroU16>() {
508                                        if number >= 1.0 && number <= u16::MAX as f64 {
509                                            let value = NonZeroU16::new(number as u16).unwrap();
510                                            wip = wip.put::<NonZeroU16>(value).unwrap();
511                                        } else {
512                                            bail!(JsonErrorKind::NumberOutOfRange(number));
513                                        }
514                                    } else if shape.is_type::<NonZeroU32>() {
515                                        if number >= 1.0 && number <= u32::MAX as f64 {
516                                            let value = NonZeroU32::new(number as u32).unwrap();
517                                            wip = wip.put::<NonZeroU32>(value).unwrap();
518                                        } else {
519                                            bail!(JsonErrorKind::NumberOutOfRange(number));
520                                        }
521                                    } else if shape.is_type::<NonZeroU64>() {
522                                        if number >= 1.0 && number <= u64::MAX as f64 {
523                                            let value = NonZeroU64::new(number as u64).unwrap();
524                                            wip = wip.put::<NonZeroU64>(value).unwrap();
525                                        } else {
526                                            bail!(JsonErrorKind::NumberOutOfRange(number));
527                                        }
528                                    } else if shape.is_type::<NonZeroUsize>() {
529                                        if number >= 1.0 && number <= usize::MAX as f64 {
530                                            let value = NonZeroUsize::new(number as usize).unwrap();
531                                            wip = wip.put::<NonZeroUsize>(value).unwrap();
532                                        } else {
533                                            bail!(JsonErrorKind::NumberOutOfRange(number));
534                                        }
535                                    } else if shape.is_type::<NonZeroI8>() {
536                                        if number >= 1.0 && number <= i8::MAX as f64 {
537                                            let value = NonZeroI8::new(number as i8).unwrap();
538                                            wip = wip.put::<NonZeroI8>(value).unwrap();
539                                        } else {
540                                            bail!(JsonErrorKind::NumberOutOfRange(number));
541                                        }
542                                    } else if shape.is_type::<NonZeroI16>() {
543                                        if number >= 1.0 && number <= i16::MAX as f64 {
544                                            let value = NonZeroI16::new(number as i16).unwrap();
545                                            wip = wip.put::<NonZeroI16>(value).unwrap();
546                                        } else {
547                                            bail!(JsonErrorKind::NumberOutOfRange(number));
548                                        }
549                                    } else if shape.is_type::<NonZeroI32>() {
550                                        if number >= 1.0 && number <= i32::MAX as f64 {
551                                            let value = NonZeroI32::new(number as i32).unwrap();
552                                            wip = wip.put::<NonZeroI32>(value).unwrap();
553                                        } else {
554                                            bail!(JsonErrorKind::NumberOutOfRange(number));
555                                        }
556                                    } else if shape.is_type::<NonZeroI64>() {
557                                        if number >= 1.0 && number <= i64::MAX as f64 {
558                                            let value = NonZeroI64::new(number as i64).unwrap();
559                                            wip = wip.put::<NonZeroI64>(value).unwrap();
560                                        } else {
561                                            bail!(JsonErrorKind::NumberOutOfRange(number));
562                                        }
563                                    } else if shape.is_type::<NonZeroIsize>() {
564                                        if number >= 1.0 && number <= isize::MAX as f64 {
565                                            let value = NonZeroIsize::new(number as isize).unwrap();
566                                            wip = wip.put::<NonZeroIsize>(value).unwrap();
567                                        } else {
568                                            bail!(JsonErrorKind::NumberOutOfRange(number));
569                                        }
570                                    } else {
571                                        todo!("number type, but unknown")
572                                    }
573                                }
574                                ScalarAffinity::String(_sa) => {
575                                    if shape.is_type::<String>() {
576                                        let value = number.to_string();
577                                        bail!(JsonErrorKind::StringAsNumber(value));
578                                    } else {
579                                        todo!()
580                                    }
581                                }
582                                _ => {
583                                    todo!("saw number in JSON but expected.. shape {}?", shape)
584                                }
585                            },
586                            _ => {
587                                todo!("saw number in JSON but expected.. shape {}?", shape)
588                            }
589                        }
590
591                        match why {
592                            WhyValue::TopLevel => {}
593                            WhyValue::ObjectKey => todo!(),
594                            WhyValue::ObjectValue => {
595                                wip = wip.pop().unwrap();
596                            }
597                            WhyValue::ArrayElement => {
598                                wip = wip.pop().unwrap();
599                            }
600                        }
601                    }
602                    b'n' => {
603                        // wow it's a null — probably
604                        let slice_rest = &input[pos..];
605                        if slice_rest.starts_with(b"null") {
606                            pos += 4;
607
608                            // ok but we already pushed some! luckily wip has the method for us
609                            wip = wip.pop_some_push_none().unwrap();
610
611                            match why {
612                                WhyValue::TopLevel => {}
613                                WhyValue::ObjectKey => todo!(),
614                                WhyValue::ObjectValue => {
615                                    // these are all super messy, they should be expect on the stack
616                                    wip = wip.pop().unwrap();
617                                }
618                                WhyValue::ArrayElement => {
619                                    wip = wip.pop().unwrap();
620                                }
621                            }
622                        } else {
623                            bail!(JsonErrorKind::UnexpectedCharacter('n'));
624                        }
625                    }
626                    c => {
627                        bail!(JsonErrorKind::UnexpectedCharacter(c as char));
628                    }
629                }
630            }
631            Expect::Separator(separator) => match separator {
632                Separator::Colon => match c {
633                    b':' => {
634                        pos += 1;
635                    }
636                    _ => {
637                        bail!(JsonErrorKind::UnexpectedCharacter(c as char));
638                    }
639                },
640                Separator::Comma(why) => match c {
641                    b',' => {
642                        pos += 1;
643                        match why {
644                            WhyComma::Array => {
645                                stack.push(Expect::Separator(Separator::Comma(WhyComma::Array)));
646                                stack.push(Expect::Value(WhyValue::ArrayElement));
647                                wip = wip.push().unwrap();
648                            }
649                            WhyComma::Object => {
650                                // looks like we're in for another round of object parsing
651                                stack.push(Expect::Separator(Separator::Comma(WhyComma::Object)));
652                                stack.push(Expect::Value(WhyValue::ObjectValue));
653                                stack.push(Expect::Separator(Separator::Colon));
654                                stack.push(Expect::Value(WhyValue::ObjectKey));
655                            }
656                        }
657                    }
658                    b'}' => {
659                        match why {
660                            WhyComma::Object => {
661                                pos += 1;
662
663                                // we finished the object, neat
664                                if frame_count > 1 {
665                                    wip = wip.pop().unwrap();
666                                }
667                            }
668                            _ => {
669                                bail!(JsonErrorKind::UnexpectedCharacter(c as char));
670                            }
671                        }
672                    }
673                    b']' => {
674                        pos += 1;
675                        match why {
676                            WhyComma::Array => {
677                                // we finished the array, neat
678                                if frame_count > 1 {
679                                    wip = wip.pop().unwrap();
680                                }
681                            }
682                            _ => {
683                                bail!(JsonErrorKind::UnexpectedCharacter(c as char));
684                            }
685                        }
686                    }
687                    _ => {
688                        bail!(JsonErrorKind::UnexpectedCharacter(c as char));
689                    }
690                },
691            },
692        }
693    }
694}