1#[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
21fn 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#[derive(Debug, Default)]
33struct StreamState {
34 done: bool,
36 parser: Parser,
38 skipping: Option<usize>,
41 failed: bool,
43 ended: bool,
45 pos: usize,
47 value: Option<Value>,
49}
50
51#[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 Scalar,
64 Structure,
66}
67
68fn frame_all(state: &mut StreamState, input: &[u8], eof: bool) -> Result<Frame, Error> {
69 if state.done {
70 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
93fn 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 _ => 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 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 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 value.start = 0;
207 state.pos -= start;
208 Frame::Incomplete { consumed: start }
209 }
210 }
211}
212
213fn 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 if index + 1 >= input.len() {
233 break;
234 }
235 index += 2;
236 }
237 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#[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 pub fn new() -> StreamDeserializer {
317 StreamDeserializer::with_config(&DeserializerConfig::new())
318 }
319
320 pub fn with_config(config: &DeserializerConfig) -> StreamDeserializer {
322 StreamDeserializer {
323 config: config.clone(),
324 state: StreamState::default(),
325 }
326 }
327
328 pub fn config(&self) -> &DeserializerConfig {
330 &self.config
331 }
332
333 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 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 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 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 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 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 state.skipping = Some(resume);
474 } else {
475 state.parser.reset();
476 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 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 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#[cfg(feature = "io")]
527pub fn from_reader<T: DeserializeOwned, R: Read>(reader: R) -> Result<T, Error> {
528 DeserializerConfig::new().from_reader(reader)
529}