Skip to main content

deser_json/
de.rs

1// @generated from deser-template-json/src/de.rs by
2// deser-template-json/generate.py.  Do not edit.
3use alloc::string::String;
4use alloc::sync::Arc;
5use core::marker::PhantomData;
6use core::str;
7
8use deser_core::de::{self, Deserialize, DeserializeDriver};
9use deser_core::{BytesFormat, Error, ErrorKind, Source};
10
11use crate::Trailing;
12use crate::parser::{Borrowing, Cursor, Options, Parser, Progress};
13
14/// Configures how JSON is deserialized.
15///
16/// The configuration is independent of the input so it can be created once
17/// (even as a constant) and used for many inputs.  The methods
18/// [`from_str`](Self::from_str) and [`from_slice`](Self::from_slice) work
19/// like the functions of the same name.  To create a [`Deserializer`] with
20/// the configuration use [`Deserializer::from_str_with_config`] or
21/// [`Deserializer::from_slice_with_config`].
22///
23/// ```
24/// use deser_json::DeserializerConfig;
25///
26/// const CONFIG: DeserializerConfig =
27///     DeserializerConfig::new().exact_numbers(false);
28/// let value: Vec<f64> = CONFIG.from_str("[0.10, 1e5]").unwrap();
29/// assert_eq!(value, [0.1, 1e5]);
30/// ```
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct DeserializerConfig {
33    track_locations: bool,
34    exact_numbers: bool,
35    trailing: Trailing,
36    bytes: BytesFormat,
37}
38
39impl Default for DeserializerConfig {
40    fn default() -> DeserializerConfig {
41        DeserializerConfig::new()
42    }
43}
44
45impl DeserializerConfig {
46    /// Creates the default configuration.
47    pub const fn new() -> DeserializerConfig {
48        DeserializerConfig {
49            track_locations: false,
50            exact_numbers: true,
51            trailing: Trailing::Strict,
52            bytes: BytesFormat::BASE64,
53        }
54    }
55
56    /// Sets how strings are decoded into bytes.
57    ///
58    /// JSON has no bytes, types that expect bytes (like `Vec<u8>`) accept
59    /// strings and sequences of integers instead.  By default strings are
60    /// decoded as base64, both with the standard and the URL-safe alphabet
61    /// and with or without padding.  This changes how strings are decoded,
62    /// for [`BytesFormat::SEQ`] they are still decoded as base64.
63    ///
64    /// ```
65    /// let value: Vec<u8> =
66    ///     deser_json::from_str(r#""Af8=""#).unwrap();
67    /// assert_eq!(value, [1, 255]);
68    /// let value: Vec<u8> =
69    ///     deser_json::from_str(r#""Af8""#).unwrap();
70    /// assert_eq!(value, [1, 255]);
71    /// let value: Vec<u8> =
72    ///     deser_json::from_str("[1, 255]").unwrap();
73    /// assert_eq!(value, [1, 255]);
74    /// ```
75    ///
76    /// Strings in other encodings than base64 need this, for instance hex
77    /// (`BytesFormat::encoded::<deser_encoding::Hex>()` with
78    /// [`deser-encoding`](https://docs.rs/deser-encoding)).
79    ///
80    /// The format is placed into the state (see [bytes](deser_core::adapters#bytes)).  Values
81    /// that use an adapter for bytes are not affected.
82    pub const fn bytes(mut self, format: BytesFormat) -> DeserializerConfig {
83        self.bytes = format;
84        self
85    }
86
87    /// Controls what may follow a value.
88    ///
89    /// By default ([`Trailing::Strict`]) only whitespace may follow the
90    /// value.  [`Trailing::Newline`] reads [JSON
91    /// Lines](https://jsonlines.org/) and [`Trailing::Stop`] stops after
92    /// the value without looking at what follows:
93    ///
94    /// ```
95    /// use deser_json::{DeserializerConfig, Trailing};
96    ///
97    /// assert!(
98    ///     deser_json::from_str::<Vec<u32>>("[1] trash")
99    ///         .is_err()
100    /// );
101    /// const STOP: DeserializerConfig =
102    ///     DeserializerConfig::new().trailing(Trailing::Stop);
103    /// assert_eq!(STOP.from_str::<Vec<u32>>("[1] trash").unwrap(), [1]);
104    /// ```
105    ///
106    /// With [`Trailing::Newline`] a [`Deserializer`] reads the lines one by
107    /// one.  Errors only discard their line:
108    ///
109    /// ```
110    /// use deser_json::{
111    ///     Deserializer, DeserializerConfig, Trailing,
112    /// };
113    ///
114    /// const LINES: DeserializerConfig =
115    ///     DeserializerConfig::new().trailing(Trailing::Newline);
116    /// let mut de =
117    ///     Deserializer::from_str_with_config("1\n\nnope\n3\n", &LINES);
118    /// let mut values = Vec::new();
119    /// while !de.is_end() {
120    ///     match de.deserialize::<u32>() {
121    ///         Ok(value) => values.push(value),
122    ///         Err(err) => assert_eq!(err.line(), Some(3)),
123    ///     }
124    /// }
125    /// assert_eq!(values, [1, 3]);
126    /// ```
127    pub const fn trailing(mut self, trailing: Trailing) -> DeserializerConfig {
128        self.trailing = trailing;
129        self
130    }
131
132    /// Returns what may follow a value.
133    pub(crate) fn trailing_mode(&self) -> Trailing {
134        self.trailing
135    }
136
137    /// Returns how strings are decoded into bytes.
138    pub(crate) fn bytes_format(&self) -> BytesFormat {
139        self.bytes
140    }
141
142    /// Returns `true` if exact numbers are enabled.
143    pub(crate) fn exact_numbers_enabled(&self) -> bool {
144        self.exact_numbers
145    }
146
147    /// Enables or disables location tracking.
148    ///
149    /// The byte range of every event is always published into the state
150    /// (see [`State::input_range`](deser_core::State::input_range)).  When
151    /// enabled additionally the input is set as source (see
152    /// [`Source`](deser_core::Source)) which allows resolving the
153    /// ranges into lines and columns, for instance with the `Spanned` type
154    /// of [`deser-location`](https://docs.rs/deser-location).  This copies
155    /// the input.
156    pub const fn track_locations(mut self, yes: bool) -> DeserializerConfig {
157        self.track_locations = yes;
158        self
159    }
160
161    /// Enables or disables exact numbers.
162    ///
163    /// When enabled (which is the default) floats which lose precision as
164    /// `f64` and integers that do not fit into 128 bits are emitted as
165    /// [`Number`](deser_core::ext::Number) extension values.  These carry the
166    /// text of the number together with its value as `f64`, which is what
167    /// types that do not know about exact numbers receive.  Types like
168    /// [`Decimal`](deser_core::ext::Decimal) (and the types of `rust_decimal` or
169    /// `bigdecimal`) use the text to deserialize the number exactly:
170    ///
171    /// ```
172    /// use deser::ext::Decimal;
173    ///
174    /// let value: Decimal =
175    ///     deser_json::from_str("0.10000000000000000001")
176    ///         .unwrap();
177    /// assert_eq!(value.as_str(), "0.10000000000000000001");
178    /// let value: f64 =
179    ///     deser_json::from_str("0.10000000000000000001")
180    ///         .unwrap();
181    /// assert_eq!(value, 0.1);
182    /// ```
183    ///
184    /// Floats whose text is the shortest representation of their value (as
185    /// formatted by `Debug`, for instance `0.5` or `3.14`) are emitted as
186    /// plain floats as the text can be recovered from the value.  This keeps
187    /// the common case fast.  When disabled, all floats are emitted as plain
188    /// floats.
189    pub const fn exact_numbers(mut self, yes: bool) -> DeserializerConfig {
190        self.exact_numbers = yes;
191        self
192    }
193
194    /// Deserializes JSON from the given string.
195    ///
196    /// What may follow the value depends on [`trailing`](Self::trailing).
197    /// With [`Trailing::Newline`] this reads the first line.
198    pub fn from_str<'de, T: Deserialize<'de>>(&self, s: &'de str) -> Result<T, Error> {
199        Deserializer::from_str_with_config(s, self).deserialize()
200    }
201
202    /// Deserializes JSON from the given bytes.
203    ///
204    /// The input must be UTF-8.  Rather than validating the input upfront,
205    /// the strings are validated while parsing (see
206    /// [`Deserializer::from_slice`]).
207    pub fn from_slice<'de, T: Deserialize<'de>>(&self, bytes: &'de [u8]) -> Result<T, Error> {
208        Deserializer::from_slice_with_config(bytes, self).deserialize()
209    }
210}
211
212/// Deserializes a serializable from JSON.
213///
214/// Every call to [`deserialize`](Self::deserialize) reads the next value.
215/// What may follow a value is controlled by
216/// [`DeserializerConfig::trailing`].  By default only whitespace may follow
217/// so there is only a single value.  With [`Trailing::Newline`] the
218/// deserializer reads [JSON Lines](https://jsonlines.org/):
219///
220/// ```
221/// use deser_json::{
222///     Deserializer, DeserializerConfig, Trailing,
223/// };
224///
225/// let config = DeserializerConfig::new().trailing(Trailing::Newline);
226/// let mut de =
227///     Deserializer::from_str_with_config("[1, 2]\n[3]\n", &config);
228/// assert_eq!(de.deserialize::<Vec<u32>>().unwrap(), [1, 2]);
229/// assert_eq!(de.deserialize::<Vec<u32>>().unwrap(), [3]);
230/// assert!(de.is_end());
231/// ```
232///
233/// To deserialize a single value, use [`from_str`](crate::from_str) and
234/// [`from_slice`](crate::from_slice) (or the methods of the same name on
235/// [`DeserializerConfig`]).  The deserializer is also useful to
236/// [`drive`](Self::drive) a custom sink.
237pub struct Deserializer<'a> {
238    input: &'a [u8],
239    pos: usize,
240    parser: Parser,
241    // `true` if the input is a byte slice which needs to be validated
242    validate_utf8: bool,
243    // `true` if a value failed and the stream cannot be continued
244    failed: bool,
245    // the input as source for location tracking, shared by all values
246    source: Option<Arc<str>>,
247    config: DeserializerConfig,
248}
249
250impl<'a> Deserializer<'a> {
251    /// Creates a new deserializer for a string.
252    #[allow(clippy::should_implement_trait)]
253    pub fn from_str(input: &'a str) -> Deserializer<'a> {
254        Deserializer::from_str_with_config(input, &DeserializerConfig::new())
255    }
256
257    /// Creates a new deserializer for a string with the given configuration.
258    pub fn from_str_with_config(input: &'a str, config: &DeserializerConfig) -> Deserializer<'a> {
259        Deserializer {
260            // the parser works on bytes but relies on the input being valid
261            // UTF-8 when it hands out string slices.
262            input: input.as_bytes(),
263            validate_utf8: false,
264            pos: 0,
265            parser: Parser::default(),
266            failed: false,
267            source: None,
268            config: config.clone(),
269        }
270    }
271
272    /// Creates a new deserializer for a byte slice.
273    ///
274    /// The input is not validated upfront.  Instead strings are validated as
275    /// UTF-8 when they are parsed (bytes outside of strings are only ever
276    /// accepted if they are ASCII).  Invalid UTF-8 is an error.
277    pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
278        Deserializer::from_slice_with_config(input, &DeserializerConfig::new())
279    }
280
281    /// Creates a new deserializer for a byte slice with the given
282    /// configuration.
283    ///
284    /// See [`from_slice`](Self::from_slice).
285    pub fn from_slice_with_config(
286        input: &'a [u8],
287        config: &DeserializerConfig,
288    ) -> Deserializer<'a> {
289        Deserializer {
290            input,
291            validate_utf8: true,
292            pos: 0,
293            parser: Parser::default(),
294            failed: false,
295            source: None,
296            config: config.clone(),
297        }
298    }
299
300    /// Creates a deserializer for the frame of a value in a stream.
301    ///
302    /// Only whitespace may follow the value in the frame.
303    pub(crate) fn from_frame(input: &'a [u8], config: &DeserializerConfig) -> Deserializer<'a> {
304        let mut de = Deserializer::from_slice_with_config(input, config);
305        de.config.trailing = Trailing::Strict;
306        de
307    }
308
309    /// Returns the configuration.
310    pub fn config(&self) -> &DeserializerConfig {
311        &self.config
312    }
313
314    /// Returns the current offset in the input.
315    pub fn offset(&self) -> usize {
316        self.pos
317    }
318
319    /// Returns `true` if there are no more values.
320    ///
321    /// This is the case if only whitespace is left or if a value failed and
322    /// the stream cannot be continued (see [`deserialize`](Self::deserialize)).
323    pub fn is_end(&self) -> bool {
324        self.failed || self.next_token() == self.input.len()
325    }
326
327    /// Fails if there is more than whitespace left.
328    ///
329    /// This is useful with [`Trailing::Stop`] to check that the input was
330    /// consumed.
331    pub fn end(&self) -> Result<(), Error> {
332        if self.is_end() {
333            return Ok(());
334        }
335        Err(Error::new(ErrorKind::Unexpected, "garbage after input")
336            .with_offset(self.next_token())
337            .resolve_position(self.input))
338    }
339
340    /// Returns where the next token starts (or the end of the input).
341    fn next_token(&self) -> usize {
342        let mut cursor = Cursor::new(self.input, self.pos);
343        cursor.parse_whitespace();
344        cursor.pos
345    }
346
347    /// Returns the input as string for the source.
348    fn source(&self) -> alloc::borrow::Cow<'a, str> {
349        if self.validate_utf8 {
350            // invalid UTF-8 fails the parsing when reached, the offsets of
351            // the tokens before it are not affected by the replacements.
352            String::from_utf8_lossy(self.input)
353        } else {
354            // SAFETY: the input was created from a string
355            alloc::borrow::Cow::Borrowed(unsafe { str::from_utf8_unchecked(self.input) })
356        }
357    }
358
359    /// Deserializes the next value.
360    ///
361    /// What may follow the value depends on
362    /// [`DeserializerConfig::trailing`].  Fails with
363    /// [`ErrorKind::EndOfFile`] if there are no more values.
364    ///
365    /// If a value fails to deserialize (because it's malformed or does not
366    /// match the type), the stream ends: [`is_end`](Self::is_end) returns
367    /// `true` and further calls fail.  With [`Trailing::Newline`] only the
368    /// rest of the line is skipped and the next call continues with the
369    /// next line.
370    ///
371    /// To configure the deserialization (for instance to add layers) use
372    /// [`deserialize_with`](Self::deserialize_with).
373    pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
374        de::Deserializer::deserialize(self)
375    }
376
377    /// Deserializes the next value with a configured driver.
378    ///
379    /// The callback is invoked with the driver before the value is
380    /// deserialized, for instance to add [`Layer`](deser_core::de::Layer)s.
381    pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
382    where
383        T: Deserialize<'a>,
384        F: FnOnce(&mut DeserializeDriver<'_, 'a>),
385    {
386        de::Deserializer::deserialize_with(self, setup)
387    }
388
389    /// Returns an iterator over the remaining values.
390    ///
391    /// This is useful to read JSON Lines (see [`Trailing::Newline`]).  The
392    /// iterator stops after the first error.
393    ///
394    /// ```
395    /// use deser_json::{
396    ///     Deserializer, DeserializerConfig, Trailing,
397    /// };
398    ///
399    /// let config = DeserializerConfig::new().trailing(Trailing::Newline);
400    /// let mut de = Deserializer::from_str_with_config("1\n2\n3\n", &config);
401    /// let items = de.iter::<u32>().collect::<Result<Vec<_>, _>>().unwrap();
402    /// assert_eq!(items, [1, 2, 3]);
403    /// ```
404    pub fn iter<T: Deserialize<'a>>(&mut self) -> Iter<'_, 'a, T> {
405        Iter {
406            de: self,
407            failed: false,
408            _marker: PhantomData,
409        }
410    }
411
412    /// Parses the next value and feeds the events into the given driver.
413    ///
414    /// This is useful to deserialize into a custom [`Sink`](deser_core::de::Sink).
415    /// See also [`deserialize_with`](Self::deserialize_with).
416    ///
417    /// Strings without escape sequences are passed on borrowed from the
418    /// input (see [`emit_borrowed`](DeserializeDriver::emit_borrowed)).
419    /// Errors carry the location in the input (see [`Error::line`]).
420    pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
421        if self.failed {
422            return Err(Error::new(
423                ErrorKind::Unexpected,
424                "cannot continue after an error",
425            ));
426        }
427        if self.config.track_locations {
428            let source = match self.source {
429                Some(ref source) => source.clone(),
430                None => {
431                    let source: Arc<str> = self.source().into();
432                    self.source = Some(source.clone());
433                    source
434                }
435            };
436            Source::set(driver.state_mut(), source);
437        }
438        if self.config.bytes != BytesFormat::BASE64 {
439            self.config.bytes.set(driver.state_mut());
440        }
441
442        // for JSON Lines the input is cut off at the end of the line.  The
443        // parser then fails if the value does not end on the line.
444        let input = self.input;
445        let line_end = if self.config.trailing == Trailing::Newline {
446            self.skip_whitespace();
447            let end = input[self.pos..]
448                .iter()
449                .position(|&b| b == b'\n')
450                .map_or(input.len(), |idx| self.pos + idx);
451            self.input = &input[..end];
452            Some(end)
453        } else {
454            None
455        };
456
457        let rv = self.drive_impl(driver);
458        self.input = input;
459
460        let rv = rv.map_err(|err| self.locate_error(err));
461        match line_end {
462            // the rest of the line is skipped, even after errors
463            Some(end) => self.pos = end,
464            // after an error the position within the value is unknown
465            None => self.failed = rv.is_err() && !self.is_end(),
466        }
467        rv
468    }
469
470    /// Attaches the location to an error.
471    #[cold]
472    fn locate_error(&self, err: Error) -> Error {
473        // errors of the parser are located at the current position, errors
474        // of the sinks at the event that failed
475        let err = match err.offset() {
476            Some(_) => err,
477            None => err.with_offset(self.pos),
478        };
479        err.resolve_position(self.input)
480    }
481
482    fn drive_impl(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
483        let options = Options {
484            validate_utf8: self.validate_utf8,
485            exact_numbers: self.config.exact_numbers,
486        };
487        let mut out = Borrowing(driver);
488        match self
489            .parser
490            .parse(self.input, self.pos, true, 0, options, &mut out)
491        {
492            Ok(Progress::Done(pos)) => {
493                self.pos = pos;
494                self.finish_value()
495            }
496            Ok(Progress::NeedMore(_)) => unreachable!("the input is complete"),
497            Err(err) => {
498                self.parser.reset();
499                Err(err)
500            }
501        }
502    }
503
504    /// Skips whitespace.
505    fn skip_whitespace(&mut self) {
506        self.pos = self.next_token();
507    }
508
509    /// Checks what follows a complete value.
510    #[inline]
511    fn finish_value(&mut self) -> Result<(), Error> {
512        let msg = match self.config.trailing {
513            Trailing::Strict => "garbage after input",
514            // the input was cut off at the end of the line
515            Trailing::Newline => "expected end of line after value",
516            Trailing::Stop => return Ok(()),
517        };
518        self.skip_whitespace();
519        if self.pos < self.input.len() {
520            return Err(Error::new(ErrorKind::Unexpected, msg));
521        }
522        Ok(())
523    }
524}
525
526/// An iterator over the values of a JSON stream.
527///
528/// See [`Deserializer::iter`].
529pub struct Iter<'b, 'a, T> {
530    de: &'b mut Deserializer<'a>,
531    failed: bool,
532    _marker: PhantomData<fn() -> T>,
533}
534
535impl<'b, 'a, T: Deserialize<'a>> Iterator for Iter<'b, 'a, T> {
536    type Item = Result<T, Error>;
537
538    fn next(&mut self) -> Option<Self::Item> {
539        if self.failed || self.de.is_end() {
540            return None;
541        }
542        let rv = self.de.deserialize();
543        self.failed = rv.is_err();
544        Some(rv)
545    }
546}
547
548impl<'a> de::Deserializer<'a> for Deserializer<'a> {
549    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
550        Deserializer::drive(self, driver)
551    }
552}
553
554/// Deserializes JSON from the given string.
555///
556/// The input must contain exactly one value, only whitespace may follow it.
557/// To read multiple values (for instance JSON Lines) use a [`Deserializer`]
558/// with [`Trailing::Newline`].  This uses the default
559/// [`DeserializerConfig`].
560pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
561    DeserializerConfig::new().from_str(s)
562}
563
564/// Deserializes JSON from the given bytes.
565///
566/// The input must be UTF-8.  Rather than validating the input upfront, the
567/// strings are validated while parsing (see [`Deserializer::from_slice`]).
568/// This uses the default [`DeserializerConfig`].
569pub fn from_slice<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Error> {
570    DeserializerConfig::new().from_slice(bytes)
571}