use super::deserializer::Deserializer;
use super::read::Fused;
use super::read::Read;
use crate::error::{Error, ErrorCode, Result};
use core::iter::FusedIterator;
use core::marker::PhantomData;
use serde::de;
pub struct StreamDeserializer<'de, R, T> {
pub(crate) de: Deserializer<R>,
pub(crate) offset: usize,
pub(crate) failed: bool,
pub(crate) output: PhantomData<T>,
pub(crate) lifetime: PhantomData<&'de ()>,
}
impl<'de, R, T> StreamDeserializer<'de, R, T>
where
R: Read<'de>,
T: de::Deserialize<'de>,
{
pub fn new(read: R) -> Self {
let offset = read.byte_offset();
StreamDeserializer {
de: Deserializer::new(read),
offset,
failed: false,
output: PhantomData,
lifetime: PhantomData,
}
}
pub fn byte_offset(&self) -> usize {
self.offset
}
fn peek_end_of_value(&mut self) -> Result<()> {
match self.de.peek()? {
Some(b' ' | b'\n' | b'\t' | b'\r' | b'{' | b'}' | b'[' | b']' | b':') | None => Ok(()),
Some(_) => {
let position = self.de.read.peek_position();
Err(Error::syntax(
ErrorCode::TrailingCharacters,
position.line,
position.column,
))
}
}
}
}
impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T>
where
R: Read<'de>,
T: de::Deserialize<'de>,
{
type Item = Result<T>;
fn next(&mut self) -> Option<Result<T>> {
if R::SHOULD_EARLY_RETURN_IF_FAILED && self.failed {
return None;
}
match self.de.parse_whitespace() {
Ok(None) => {
self.offset = self.de.read.byte_offset();
None
}
Ok(Some(b)) => {
let self_delineated_value = match b {
b'{' | b'[' => true,
_ => false,
};
self.offset = self.de.read.byte_offset();
let result = de::Deserialize::deserialize(&mut self.de);
Some(match result {
Ok(value) => {
self.offset = self.de.read.byte_offset();
if self_delineated_value {
Ok(value)
} else {
self.peek_end_of_value().map(|()| value)
}
}
Err(e) => {
self.de.read.set_failed(&mut self.failed);
Err(e)
}
})
}
Err(e) => {
self.de.read.set_failed(&mut self.failed);
Some(Err(e))
}
}
}
}
impl<'de, R, T> FusedIterator for StreamDeserializer<'de, R, T>
where
R: Read<'de> + Fused,
T: de::Deserialize<'de>,
{
}