Skip to main content

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