Skip to main content

deser_json/
stream.rs

1// @generated from deser-template-json/src/stream.rs by
2// deser-template-json/generate.py.  Do not edit.
3//! Reading JSON streams.
4#[cfg(feature = "io")]
5use std::io::Read;
6
7#[cfg(feature = "io")]
8use deser_core::de::DeserializeOwned;
9use deser_core::de::{self, DeserializeDriver, Frame, Progress};
10use deser_core::{Error, ErrorKind, State};
11
12use crate::Trailing;
13use crate::de::{Deserializer, DeserializerConfig};
14use crate::parser::{Copying, Discard, Options, Parser, Progress as ParseProgress};
15use crate::scan::skip_to_escape;
16
17fn is_whitespace(byte: u8) -> bool {
18    matches!(byte, b' ' | b'\n' | b'\t' | b'\r')
19}
20
21/// Returns where the next token starts and if it's there.
22///
23/// At the end of the input there is no token.
24fn skip_whitespace(input: &[u8], pos: usize, _eof: bool) -> (usize, bool) {
25    match input[pos..].iter().position(|&b| !is_whitespace(b)) {
26        Some(index) => (pos + index, true),
27        None => (input.len(), false),
28    }
29}
30
31/// The state of a JSON stream that is read.
32#[derive(Debug, Default)]
33struct StreamState {
34    // `Trailing::Strict`: the value was read
35    done: bool,
36    // parses values while their input arrives (see `drive_partial`)
37    parser: Parser,
38    // the rest of a value that failed in a sink is skipped from the
39    // position in the input
40    skipping: Option<usize>,
41    // parsing failed, the stream cannot be continued
42    failed: bool,
43    // the stream ended within a value
44    ended: bool,
45    // the position up to which the input was scanned
46    pos: usize,
47    // `Trailing::Stop`: the value being scanned
48    value: Option<Value>,
49}
50
51/// The state of the scan of a value.
52#[derive(Debug)]
53struct Value {
54    start: usize,
55    kind: ValueKind,
56    depth: usize,
57    in_string: bool,
58}
59
60#[derive(Debug)]
61enum ValueKind {
62    /// A number or literal, which is scanned by parsing it (`1-2` is two
63    /// numbers).  The parser consumed the input up to `start + parsed`.
64    Scalar { parser: Parser, parsed: usize },
65    /// A string, map or sequence.
66    Structure,
67}
68
69fn frame_all(state: &mut StreamState, input: &[u8], eof: bool) -> Result<Frame, Error> {
70    if state.done {
71        // only whitespace may follow the value
72        return trailing_whitespace(input, 0, eof).map(|progress| match progress {
73            Progress::End => Frame::End,
74            Progress::NeedMore { consumed } => Frame::Incomplete { consumed },
75            Progress::Done { .. } => unreachable!(),
76        });
77    }
78    if !eof {
79        return Ok(Frame::Incomplete { consumed: 0 });
80    }
81    let (start, _) = skip_whitespace(input, 0, eof);
82    Ok(if start < input.len() {
83        state.done = true;
84        Frame::Value {
85            start,
86            end: input.len(),
87            consumed: input.len(),
88        }
89    } else {
90        Frame::End
91    })
92}
93
94/// Checks that only whitespace follows a value.
95///
96/// `offset` is the offset of the input in the stream for errors.
97fn trailing_whitespace(input: &[u8], offset: usize, eof: bool) -> Result<Progress, Error> {
98    match skip_whitespace(input, 0, eof) {
99        (pos, _) if pos == input.len() && eof => Ok(Progress::End),
100        (pos, false) if !eof => Ok(Progress::NeedMore { consumed: pos }),
101        (pos, _) => Err(Error::with_offset(
102            ErrorKind::Syntax,
103            "garbage after input",
104            offset + pos,
105        )),
106    }
107}
108
109fn frame_line(state: &mut StreamState, input: &[u8], eof: bool) -> Frame {
110    // whitespace before the value is skipped first like the deserializer
111    // does, comments in it can span lines
112    if state.pos == 0 {
113        match skip_whitespace(input, 0, eof) {
114            (0, true) => {}
115            (start, true) => return Frame::Incomplete { consumed: start },
116            (_, false) if input.is_empty() && eof => return Frame::End,
117            (start, false) => return Frame::Incomplete { consumed: start },
118        }
119    }
120    let end = input[state.pos..]
121        .iter()
122        .position(|&b| b == b'\n')
123        .map(|index| state.pos + index);
124    let end = match end {
125        Some(end) => end,
126        None if eof => input.len(),
127        None => {
128            state.pos = input.len();
129            return Frame::Incomplete { consumed: 0 };
130        }
131    };
132    state.pos = 0;
133    let consumed = (end + 1).min(input.len());
134    match skip_whitespace(&input[..end], 0, true) {
135        (start, _) if start < end => Frame::Value {
136            start,
137            end,
138            consumed,
139        },
140        _ if consumed == 0 => Frame::End,
141        // blank lines are skipped
142        _ => Frame::Incomplete { consumed },
143    }
144}
145
146fn frame_value(state: &mut StreamState, input: &[u8], eof: bool) -> Frame {
147    let value = match state.value {
148        Some(ref mut value) => value,
149        None => {
150            let start = match skip_whitespace(input, 0, eof) {
151                (start, true) => start,
152                (_, false) if input.is_empty() && eof => return Frame::End,
153                (consumed, false) => return Frame::Incomplete { consumed },
154            };
155            let (kind, depth, in_string) = match input[start] {
156                b'"' => (ValueKind::Structure, 0, true),
157                b'{' | b'[' => (ValueKind::Structure, 1, false),
158                // a value cannot start with these, the parser reports the
159                // error
160                b'}' | b']' | b',' | b':' => {
161                    return Frame::Value {
162                        start,
163                        end: start + 1,
164                        consumed: start + 1,
165                    };
166                }
167                _ => (
168                    ValueKind::Scalar {
169                        parser: Parser::default(),
170                        parsed: 0,
171                    },
172                    0,
173                    false,
174                ),
175            };
176            state.pos = start + 1;
177            state.value.insert(Value {
178                start,
179                kind,
180                depth,
181                in_string,
182            })
183        }
184    };
185
186    let end = match value.kind {
187        ValueKind::Scalar {
188            ref mut parser,
189            ref mut parsed,
190        } => {
191            let pos = value.start + *parsed;
192            let options = Options {
193                validate_utf8: true,
194                exact_numbers: false,
195            };
196            let mut discard = Discard(State::new());
197            match parser.parse(&input[pos..], 0, eof, 0, options, &mut discard) {
198                Ok(ParseProgress::Done(end)) => Some(pos + end),
199                Ok(ParseProgress::NeedMore(consumed)) => {
200                    *parsed += consumed;
201                    state.pos = input.len();
202                    None
203                }
204                // the value ends at the error, the parser reports it when
205                // the value is deserialized
206                Err(err) => Some(error_end(&err, input, pos)),
207            }
208        }
209        ValueKind::Structure => scan_structure(input, &mut state.pos, value),
210    };
211
212    let start = value.start;
213    match end {
214        Some(end) => {
215            state.value = None;
216            state.pos = 0;
217            Frame::Value {
218                start,
219                end,
220                consumed: end,
221            }
222        }
223        // the value is incomplete, the parser reports the error
224        None if eof => {
225            state.value = None;
226            state.pos = 0;
227            Frame::Value {
228                start,
229                end: input.len(),
230                consumed: input.len(),
231            }
232        }
233        None => {
234            // discard the whitespace before the value
235            value.start = 0;
236            state.pos -= start;
237            Frame::Incomplete { consumed: start }
238        }
239    }
240}
241
242/// Returns where the frame of a value which failed to parse ends.
243///
244/// The frame ends after the byte that failed, the parser fails there
245/// again when the value is deserialized.  If the input ended within the
246/// value (where the error is located at the start of the token, like a
247/// comment, which is valid if it's cut off) the frame is the rest of the
248/// input.
249fn error_end(err: &Error, input: &[u8], pos: usize) -> usize {
250    match err.offset() {
251        Some(offset) if err.kind() != ErrorKind::EndOfFile => (pos + offset + 1).min(input.len()),
252        _ => input.len(),
253    }
254}
255
256/// Scans a string, map or sequence from `pos`.
257///
258/// Returns the end of the value if it's complete.
259fn scan_structure(input: &[u8], pos: &mut usize, value: &mut Value) -> Option<usize> {
260    let mut index = *pos;
261    while index < input.len() {
262        if value.in_string {
263            index = skip_to_escape(input, index);
264            let byte = input.get(index).copied();
265            match byte {
266                Some(b'"') => {
267                    value.in_string = false;
268                    index += 1;
269                    if value.depth == 0 {
270                        return Some(index);
271                    }
272                }
273                Some(b'\\') => {
274                    // the escaped byte is scanned again with more input
275                    if index + 1 >= input.len() {
276                        break;
277                    }
278                    index += 2;
279                }
280                // control characters are reported by the parser
281                Some(_) => index += 1,
282                None => break,
283            }
284        } else {
285            match input[index] {
286                b'"' => {
287                    value.in_string = true;
288                }
289                b'{' | b'[' => value.depth += 1,
290                b'}' | b']' => {
291                    value.depth -= 1;
292                    if value.depth == 0 {
293                        return Some(index + 1);
294                    }
295                }
296                _ => {}
297            }
298            index += 1;
299        }
300    }
301    *pos = index;
302    None
303}
304
305/// Reads a stream of JSON values (see [`deser::stream`](deser_core::stream)).
306///
307/// How the stream is split depends on [`DeserializerConfig::set_trailing`]:
308///
309/// * [`Trailing::Strict`]: the stream holds a single value which is parsed
310///   once the whole stream was read.
311/// * [`Trailing::Newline`]: every line holds a value ([JSON
312///   Lines](https://jsonlines.org/)).  Blank lines are skipped and errors
313///   only discard their line, reading continues with the next one.
314/// * [`Trailing::Stop`]: values follow each other (optionally separated by
315///   whitespace) and are split where they end.  Numbers at the end of the
316///   stream are only complete at the end of the stream, other values are
317///   complete once their last byte was read.  Reading continues after
318///   values that fail to deserialize, values that are not valid JSON end
319///   the stream (unless they are read from their frames).
320///
321/// Except for JSON Lines, values which do not borrow are deserialized while
322/// their input arrives (see
323/// [`StreamDeserializer::drive_partial`](de::StreamDeserializer::drive_partial))
324/// so only incomplete tokens are buffered.
325///
326/// ```
327/// # #[cfg(feature = "io")] {
328/// use deser_json::{DeserializerConfig, Trailing};
329///
330/// const LINES: DeserializerConfig =
331///     DeserializerConfig::builder().trailing(Trailing::Newline).build();
332/// let mut reader = LINES.reader(&b"[1, 2]\n[3]\n"[..]);
333/// assert_eq!(reader.read::<Vec<u32>>().unwrap(), Some(vec![1, 2]));
334/// assert_eq!(reader.read::<Vec<u32>>().unwrap(), Some(vec![3]));
335/// assert_eq!(reader.read::<Vec<u32>>().unwrap(), None);
336/// # }
337/// ```
338///
339/// Values which are read from their frames are parsed like with a
340/// [`Deserializer`], so they can borrow from the stream's buffer (see
341/// [`InputBuffer::deserialize`](deser_core::stream::InputBuffer::deserialize)).  The input ranges (and thus
342/// locations) of these values refer to the start of their line (or value),
343/// those of values that are deserialized while their input arrives to the
344/// stream.
345#[derive(Debug)]
346pub struct StreamDeserializer {
347    config: DeserializerConfig,
348    state: StreamState,
349}
350
351impl Default for StreamDeserializer {
352    fn default() -> StreamDeserializer {
353        StreamDeserializer::new()
354    }
355}
356
357impl StreamDeserializer {
358    /// Creates a stream deserializer.
359    pub fn new() -> StreamDeserializer {
360        StreamDeserializer::with_config(DeserializerConfig::new())
361    }
362
363    /// Creates a stream deserializer with the given configuration.
364    pub fn with_config(config: DeserializerConfig) -> StreamDeserializer {
365        StreamDeserializer {
366            config,
367            state: StreamState::default(),
368        }
369    }
370
371    /// Returns the configuration.
372    pub fn config(&self) -> &DeserializerConfig {
373        &self.config
374    }
375
376    /// Skips what precedes the next value.
377    ///
378    /// This skips the rest of a value that failed in a sink and the
379    /// whitespace before the next value.  Returns where the value starts,
380    /// or the progress if there is no value (yet).
381    fn skip_to_value(
382        &mut self,
383        input: &[u8],
384        offset: usize,
385        eof: bool,
386    ) -> Result<Result<usize, Progress>, Error> {
387        let options = self.options();
388        let state = &mut self.state;
389        if state.ended {
390            return Ok(Err(Progress::End));
391        }
392        if state.failed {
393            return Err(Error::new(
394                ErrorKind::InvalidState,
395                "cannot continue after an error",
396            ));
397        }
398
399        // skip the rest of a value that failed in a sink
400        let mut pos = 0;
401        if let Some(skip) = state.skipping {
402            let mut discard = Discard(State::new());
403            match state
404                .parser
405                .parse(input, skip, eof, offset, options, &mut discard)
406            {
407                Ok(ParseProgress::Done(end)) => {
408                    state.skipping = None;
409                    state.done = self.config.trailing_mode() == Trailing::Strict;
410                    pos = end;
411                }
412                Ok(ParseProgress::NeedMore(consumed)) => {
413                    state.skipping = Some(0);
414                    return Ok(Err(Progress::NeedMore { consumed }));
415                }
416                Err(err) => {
417                    state.parser.reset();
418                    state.skipping = None;
419                    state.failed = true;
420                    return Err(err);
421                }
422            }
423        }
424
425        if !state.parser.is_idle() {
426            return Ok(Ok(pos));
427        }
428        if state.done {
429            return match trailing_whitespace(&input[pos..], offset + pos, eof)? {
430                Progress::NeedMore { consumed } => Ok(Err(Progress::NeedMore {
431                    consumed: pos + consumed,
432                })),
433                progress => Ok(Err(progress)),
434            };
435        }
436        // a new value, skip the whitespace before it
437        let token;
438        (pos, token) = skip_whitespace(input, pos, eof);
439        if !token && (pos == input.len() || !eof) {
440            return Ok(Err(if eof {
441                Progress::End
442            } else {
443                Progress::NeedMore { consumed: pos }
444            }));
445        }
446        Ok(Ok(pos))
447    }
448
449    /// Returns the options of the parser.
450    fn options(&self) -> Options {
451        Options {
452            validate_utf8: true,
453            exact_numbers: self.config.exact_numbers_enabled(),
454        }
455    }
456}
457
458impl de::StreamDeserializer for StreamDeserializer {
459    fn context(&self) -> deser_core::Context {
460        self.config.context().clone()
461    }
462
463    fn frame(&mut self, input: &[u8], eof: bool) -> Result<Frame, Error> {
464        let state = &mut self.state;
465        match self.config.trailing_mode() {
466            Trailing::Strict => frame_all(state, input, eof),
467            Trailing::Newline => Ok(frame_line(state, input, eof)),
468            Trailing::Stop => Ok(frame_value(state, input, eof)),
469        }
470    }
471
472    fn drive_frame<'de>(
473        &mut self,
474        frame: &'de [u8],
475        driver: &mut DeserializeDriver<'_, 'de>,
476    ) -> Result<(), Error> {
477        let mut de = Deserializer::from_frame(frame, &self.config);
478        de.drive(driver)
479    }
480
481    fn is_text(&self) -> bool {
482        true
483    }
484
485    /// JSON Lines are read line by line, the other values while their
486    /// input arrives.
487    fn supports_partial(&self) -> bool {
488        self.config.trailing_mode() != Trailing::Newline
489    }
490
491    fn drive_partial(
492        &mut self,
493        input: &[u8],
494        offset: usize,
495        eof: bool,
496        driver: &mut DeserializeDriver<'_, '_>,
497    ) -> Result<Progress, Error> {
498        let pos = match self.skip_to_value(input, offset, eof)? {
499            Ok(pos) => pos,
500            Err(progress) => return Ok(progress),
501        };
502        let options = self.options();
503        let state = &mut self.state;
504        match state
505            .parser
506            .parse(input, pos, eof, offset, options, &mut Copying(driver))
507        {
508            Ok(ParseProgress::Done(end)) => {
509                state.done = self.config.trailing_mode() == Trailing::Strict;
510                Ok(Progress::Done { consumed: end })
511            }
512            Ok(ParseProgress::NeedMore(consumed)) => Ok(Progress::NeedMore { consumed }),
513            Err(err) => {
514                if let Some(resume) = state.parser.recoverable() {
515                    // a sink failed, the next call continues after the
516                    // value.  The input is not consumed on errors.
517                    state.skipping = Some(resume);
518                } else {
519                    state.parser.reset();
520                    // after an incomplete value at the end there are no
521                    // more values
522                    state.ended = eof && err.kind() == ErrorKind::EndOfFile;
523                    state.failed = true;
524                }
525                Err(err)
526            }
527        }
528    }
529
530    fn peek(&mut self, input: &[u8], eof: bool) -> Result<Option<Progress>, Error> {
531        if !de::StreamDeserializer::supports_partial(self) {
532            return Ok(None);
533        }
534        Ok(Some(match self.skip_to_value(input, 0, eof)? {
535            Ok(pos) => Progress::Done { consumed: pos },
536            Err(progress) => progress,
537        }))
538    }
539}
540
541#[cfg(feature = "io")]
542impl DeserializerConfig {
543    /// Creates a reader of a stream of values (see
544    /// [`deser::io::Reader`](deser_core::io::Reader)).
545    ///
546    /// See [`StreamDeserializer`] for how the stream is split into values.
547    pub fn reader<R: Read>(&self, reader: R) -> deser_core::io::Reader<R, StreamDeserializer> {
548        deser_core::io::Reader::new(reader, StreamDeserializer::with_config(self.clone()))
549    }
550
551    /// Deserializes a value from a reader.
552    ///
553    /// See [`from_reader`].
554    pub fn from_reader<T: DeserializeOwned, R: Read>(&self, reader: R) -> Result<T, Error> {
555        deser_core::io::from_reader(reader, StreamDeserializer::with_config(self.clone()))
556    }
557}
558
559/// Deserializes a value from a reader.
560///
561/// The reader is read to the end.  Only whitespace may follow the value.
562/// The reader does not need to be buffered.  To read more than one value
563/// (for instance JSON Lines) use [`DeserializerConfig::reader`].
564///
565/// ```
566/// let value: Vec<u32> =
567///     deser_json::from_reader(&b"[1, 2, 3]"[..]).unwrap();
568/// assert_eq!(value, [1, 2, 3]);
569/// ```
570#[cfg(feature = "io")]
571pub fn from_reader<T: DeserializeOwned, R: Read>(reader: R) -> Result<T, Error> {
572    DeserializerConfig::new().from_reader(reader)
573}