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::{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)]
61enum ValueKind {
62 Scalar { parser: Parser, parsed: usize },
65 Structure,
67}
68
69fn frame_all(state: &mut StreamState, input: &[u8], eof: bool) -> Result<Frame, Error> {
70 if state.done {
71 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
94fn 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 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 _ => 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 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 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 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 value.start = 0;
236 state.pos -= start;
237 Frame::Incomplete { consumed: start }
238 }
239 }
240}
241
242fn 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
256fn 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 if index + 1 >= input.len() {
276 break;
277 }
278 index += 2;
279 }
280 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#[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 pub fn new() -> StreamDeserializer {
360 StreamDeserializer::with_config(DeserializerConfig::new())
361 }
362
363 pub fn with_config(config: DeserializerConfig) -> StreamDeserializer {
365 StreamDeserializer {
366 config,
367 state: StreamState::default(),
368 }
369 }
370
371 pub fn config(&self) -> &DeserializerConfig {
373 &self.config
374 }
375
376 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 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 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 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 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 state.skipping = Some(resume);
518 } else {
519 state.parser.reset();
520 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 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 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#[cfg(feature = "io")]
571pub fn from_reader<T: DeserializeOwned, R: Read>(reader: R) -> Result<T, Error> {
572 DeserializerConfig::new().from_reader(reader)
573}