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