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}