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