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, 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, _) => Err(Error::with_offset(
101 ErrorKind::Syntax,
102 "garbage after input",
103 offset + pos,
104 )),
105 }
106}
107
108fn frame_line(state: &mut StreamState, input: &[u8], eof: bool) -> Frame {
109 let end = input[state.pos..]
110 .iter()
111 .position(|&b| b == b'\n')
112 .map(|index| state.pos + index);
113 let end = match end {
114 Some(end) => end,
115 None if eof => input.len(),
116 None => {
117 state.pos = input.len();
118 return Frame::Incomplete { consumed: 0 };
119 }
120 };
121 state.pos = 0;
122 let consumed = (end + 1).min(input.len());
123 match skip_whitespace(&input[..end], 0, true) {
124 (start, _) if start < end => Frame::Value {
125 start,
126 end,
127 consumed,
128 },
129 _ if consumed == 0 => Frame::End,
130 _ => Frame::Incomplete { consumed },
132 }
133}
134
135fn frame_value(state: &mut StreamState, input: &[u8], eof: bool) -> Frame {
136 let value = match state.value {
137 Some(ref mut value) => value,
138 None => {
139 let start = match skip_whitespace(input, 0, eof) {
140 (start, true) => start,
141 (_, false) if input.is_empty() && eof => return Frame::End,
142 (consumed, false) => return Frame::Incomplete { consumed },
143 };
144 let (kind, depth, in_string) = match input[start] {
145 b'"' => (ValueKind::Structure, 0, true),
146 b'{' | b'[' => (ValueKind::Structure, 1, false),
147 b'}' | b']' | b',' | b':' => {
150 return Frame::Value {
151 start,
152 end: start + 1,
153 consumed: start + 1,
154 };
155 }
156 _ => (ValueKind::Scalar, 0, false),
157 };
158 state.pos = start + 1;
159 state.value.insert(Value {
160 start,
161 kind,
162 depth,
163 in_string,
164 })
165 }
166 };
167
168 let end = match value.kind {
169 ValueKind::Scalar => {
170 let end = input[state.pos..].iter().position(|&b| match b {
171 b'{' | b'}' | b'[' | b']' | b',' | b':' | b'"' => true,
172 _ => is_whitespace(b),
173 });
174 match end {
175 Some(index) => Some(state.pos + index),
176 None => {
177 state.pos = input.len();
178 None
179 }
180 }
181 }
182 ValueKind::Structure => scan_structure(input, &mut state.pos, value),
183 };
184
185 let start = value.start;
186 match end {
187 Some(end) => {
188 state.value = None;
189 state.pos = 0;
190 Frame::Value {
191 start,
192 end,
193 consumed: end,
194 }
195 }
196 None if eof => {
198 state.value = None;
199 state.pos = 0;
200 Frame::Value {
201 start,
202 end: input.len(),
203 consumed: input.len(),
204 }
205 }
206 None => {
207 value.start = 0;
209 state.pos -= start;
210 Frame::Incomplete { consumed: start }
211 }
212 }
213}
214
215fn scan_structure(input: &[u8], pos: &mut usize, value: &mut Value) -> Option<usize> {
219 let mut index = *pos;
220 while index < input.len() {
221 if value.in_string {
222 index = skip_to_escape(input, index);
223 let byte = input.get(index).copied();
224 match byte {
225 Some(b'"') => {
226 value.in_string = false;
227 index += 1;
228 if value.depth == 0 {
229 return Some(index);
230 }
231 }
232 Some(b'\\') => {
233 if index + 1 >= input.len() {
235 break;
236 }
237 index += 2;
238 }
239 Some(_) => index += 1,
241 None => break,
242 }
243 } else {
244 match input[index] {
245 b'"' => {
246 value.in_string = true;
247 }
248 b'{' | b'[' => value.depth += 1,
249 b'}' | b']' => {
250 value.depth -= 1;
251 if value.depth == 0 {
252 return Some(index + 1);
253 }
254 }
255 _ => {}
256 }
257 index += 1;
258 }
259 }
260 *pos = index;
261 None
262}
263
264#[derive(Debug)]
305pub struct StreamDeserializer {
306 config: DeserializerConfig,
307 state: StreamState,
308}
309
310impl Default for StreamDeserializer {
311 fn default() -> StreamDeserializer {
312 StreamDeserializer::new()
313 }
314}
315
316impl StreamDeserializer {
317 pub fn new() -> StreamDeserializer {
319 StreamDeserializer::with_config(DeserializerConfig::new())
320 }
321
322 pub fn with_config(config: DeserializerConfig) -> StreamDeserializer {
324 StreamDeserializer {
325 config,
326 state: StreamState::default(),
327 }
328 }
329
330 pub fn config(&self) -> &DeserializerConfig {
332 &self.config
333 }
334
335 fn skip_to_value(
341 &mut self,
342 input: &[u8],
343 offset: usize,
344 eof: bool,
345 ) -> Result<Result<usize, Progress>, Error> {
346 let options = self.options();
347 let state = &mut self.state;
348 if state.ended {
349 return Ok(Err(Progress::End));
350 }
351 if state.failed {
352 return Err(Error::new(
353 ErrorKind::InvalidState,
354 "cannot continue after an error",
355 ));
356 }
357
358 let mut pos = 0;
360 if let Some(skip) = state.skipping {
361 let mut discard = Discard(State::new());
362 match state
363 .parser
364 .parse(input, skip, eof, offset, options, &mut discard)
365 {
366 Ok(ParseProgress::Done(end)) => {
367 state.skipping = None;
368 state.done = self.config.trailing_mode() == Trailing::Strict;
369 pos = end;
370 }
371 Ok(ParseProgress::NeedMore(consumed)) => {
372 state.skipping = Some(0);
373 return Ok(Err(Progress::NeedMore { consumed }));
374 }
375 Err(err) => {
376 state.parser.reset();
377 state.skipping = None;
378 state.failed = true;
379 return Err(err);
380 }
381 }
382 }
383
384 if !state.parser.is_idle() {
385 return Ok(Ok(pos));
386 }
387 if state.done {
388 return match trailing_whitespace(&input[pos..], offset + pos, eof)? {
389 Progress::NeedMore { consumed } => Ok(Err(Progress::NeedMore {
390 consumed: pos + consumed,
391 })),
392 progress => Ok(Err(progress)),
393 };
394 }
395 let token;
397 (pos, token) = skip_whitespace(input, pos, eof);
398 if !token && (pos == input.len() || !eof) {
399 return Ok(Err(if eof {
400 Progress::End
401 } else {
402 Progress::NeedMore { consumed: pos }
403 }));
404 }
405 Ok(Ok(pos))
406 }
407
408 fn options(&self) -> Options {
410 Options {
411 validate_utf8: true,
412 exact_numbers: self.config.exact_numbers_enabled(),
413 }
414 }
415}
416
417impl de::StreamDeserializer for StreamDeserializer {
418 fn context(&self) -> deser_core::Context {
419 self.config.context().clone()
420 }
421
422 fn frame(&mut self, input: &[u8], eof: bool) -> Result<Frame, Error> {
423 let state = &mut self.state;
424 match self.config.trailing_mode() {
425 Trailing::Strict => frame_all(state, input, eof),
426 Trailing::Newline => Ok(frame_line(state, input, eof)),
427 Trailing::Stop => Ok(frame_value(state, input, eof)),
428 }
429 }
430
431 fn drive_frame<'de>(
432 &mut self,
433 frame: &'de [u8],
434 driver: &mut DeserializeDriver<'_, 'de>,
435 ) -> Result<(), Error> {
436 Deserializer::from_frame(frame, &self.config).drive(driver)
437 }
438
439 fn is_text(&self) -> bool {
440 true
441 }
442
443 fn supports_partial(&self) -> bool {
446 self.config.trailing_mode() != Trailing::Newline
447 }
448
449 fn drive_partial(
450 &mut self,
451 input: &[u8],
452 offset: usize,
453 eof: bool,
454 driver: &mut DeserializeDriver<'_, '_>,
455 ) -> Result<Progress, Error> {
456 let pos = match self.skip_to_value(input, offset, eof)? {
457 Ok(pos) => pos,
458 Err(progress) => return Ok(progress),
459 };
460 let options = self.options();
461 let state = &mut self.state;
462 match state
463 .parser
464 .parse(input, pos, eof, offset, options, &mut Copying(driver))
465 {
466 Ok(ParseProgress::Done(end)) => {
467 state.done = self.config.trailing_mode() == Trailing::Strict;
468 Ok(Progress::Done { consumed: end })
469 }
470 Ok(ParseProgress::NeedMore(consumed)) => Ok(Progress::NeedMore { consumed }),
471 Err(err) => {
472 if let Some(resume) = state.parser.recoverable() {
473 state.skipping = Some(resume);
476 } else {
477 state.parser.reset();
478 state.ended = eof && err.kind() == ErrorKind::EndOfFile;
481 state.failed = true;
482 }
483 Err(err)
484 }
485 }
486 }
487
488 fn peek(&mut self, input: &[u8], eof: bool) -> Result<Option<Progress>, Error> {
489 if !de::StreamDeserializer::supports_partial(self) {
490 return Ok(None);
491 }
492 Ok(Some(match self.skip_to_value(input, 0, eof)? {
493 Ok(pos) => Progress::Done { consumed: pos },
494 Err(progress) => progress,
495 }))
496 }
497}
498
499#[cfg(feature = "io")]
500impl DeserializerConfig {
501 pub fn reader<R: Read>(&self, reader: R) -> deser_core::io::Reader<R, StreamDeserializer> {
506 deser_core::io::Reader::new(reader, StreamDeserializer::with_config(self.clone()))
507 }
508
509 pub fn from_reader<T: DeserializeOwned, R: Read>(&self, reader: R) -> Result<T, Error> {
513 deser_core::io::from_reader(reader, StreamDeserializer::with_config(self.clone()))
514 }
515}
516
517#[cfg(feature = "io")]
529pub fn from_reader<T: DeserializeOwned, R: Read>(reader: R) -> Result<T, Error> {
530 DeserializerConfig::new().from_reader(reader)
531}