use crate::*;
#[inline(always)]
fn advance_whitespace<'read, R: Read<'read>, S: Stack>(
reader: &mut PeekableRead<'read, R>,
) -> Result<(), JsonError<'read, R, S>> {
let mut next;
while {
next = reader.peek();
matches!(next, b'\x20' | b'\x09' | b'\x0A' | b'\x0D')
} {
reader.read_byte().map_err(JsonError::ReadError)?;
}
Ok(())
}
#[inline(always)]
pub(super) fn advance_past_colon<'read, R: Read<'read>, S: Stack>(
reader: &mut PeekableRead<'read, R>,
) -> Result<(), JsonError<'read, R, S>> {
advance_whitespace(reader)?;
match reader.read_byte().map_err(JsonError::ReadError)? {
b':' => advance_whitespace(reader)?,
_ => Err(JsonError::InvalidKeyValueDelimiter)?,
}
Ok(())
}
#[inline(always)]
pub(super) fn advance_past_comma_or_to_close<'read, R: Read<'read>, S: Stack>(
reader: &mut PeekableRead<'read, R>,
) -> Result<(), JsonError<'read, R, S>> {
advance_whitespace(reader)?;
match reader.peek() {
b',' => {
reader.read_byte().map_err(JsonError::ReadError)?;
advance_whitespace(reader)?;
if matches!(reader.peek(), b']' | b'}') {
Err(JsonError::TrailingComma)?;
}
}
b']' | b'}' => {}
_ => Err(JsonError::InvalidValue)?,
}
Ok(())
}
pub(super) enum SingleStepObjectResult {
Field,
Closed,
}
pub(super) enum SingleStepArrayResult {
Value,
Closed,
}
pub(super) enum SingleStepUnknownResult {
ObjectOpened,
ArrayOpened,
String,
Number(Number),
Bool(bool),
Null,
}
pub(super) enum SingleStepResult {
Object(SingleStepObjectResult),
Array(SingleStepArrayResult),
Unknown(SingleStepUnknownResult),
}
fn single_step<'read, 'parent, R: Read<'read>, S: Stack>(
reader: &'parent mut PeekableRead<'read, R>,
stack: &'parent mut S,
) -> Result<SingleStepResult, JsonError<'read, R, S>> {
match stack.peek().ok_or(JsonError::InternalError)? {
State::Object => {
let next = reader.peek();
if next == b'}' {
stack.pop().ok_or(JsonError::InternalError)?;
if stack.depth() != 0 {
reader.read_byte().map_err(JsonError::ReadError)?;
advance_past_comma_or_to_close(reader)?;
}
return Ok(SingleStepResult::Object(SingleStepObjectResult::Closed));
}
if next != b'"' {
Err(JsonError::InvalidKey)?;
}
reader.read_byte().map_err(JsonError::ReadError)?;
stack.push(State::Unknown).map_err(JsonError::StackError)?;
Ok(SingleStepResult::Object(SingleStepObjectResult::Field))
}
State::Array => {
if reader.peek() == b']' {
stack.pop().ok_or(JsonError::InternalError)?;
if stack.depth() != 0 {
reader.read_byte().map_err(JsonError::ReadError)?;
advance_past_comma_or_to_close(reader)?;
}
return Ok(SingleStepResult::Array(SingleStepArrayResult::Closed));
}
stack.push(State::Unknown).map_err(JsonError::StackError)?;
Ok(SingleStepResult::Array(SingleStepArrayResult::Value))
}
State::Unknown => {
stack.pop().ok_or(JsonError::InternalError)?;
let result = match kind(reader) {
Type::Object => {
reader.read_byte().map_err(JsonError::ReadError)?;
advance_whitespace(reader)?;
stack.push(State::Object).map_err(JsonError::StackError)?;
return Ok(SingleStepResult::Unknown(SingleStepUnknownResult::ObjectOpened));
}
Type::Array => {
reader.read_byte().map_err(JsonError::ReadError)?;
advance_whitespace(reader)?;
stack.push(State::Array).map_err(JsonError::StackError)?;
return Ok(SingleStepResult::Unknown(SingleStepUnknownResult::ArrayOpened));
}
Type::String => {
reader.read_byte().map_err(JsonError::ReadError)?;
return Ok(SingleStepResult::Unknown(SingleStepUnknownResult::String));
}
Type::Number => {
SingleStepResult::Unknown(SingleStepUnknownResult::Number(number::to_number_str(reader)?))
}
Type::Bool => {
let mut bool_string = [0; 4];
reader.read_exact_into_non_empty_slice(&mut bool_string).map_err(JsonError::ReadError)?;
let bool = if &bool_string == b"true" {
true
} else {
let e = reader.read_byte().map_err(JsonError::ReadError)?;
if !((bool_string == *b"fals") & (e == b'e')) {
Err(JsonError::TypeError)?;
}
false
};
SingleStepResult::Unknown(SingleStepUnknownResult::Bool(bool))
}
Type::Null => {
let mut null_string = [0; 4];
reader.read_exact_into_non_empty_slice(&mut null_string).map_err(JsonError::ReadError)?;
if null_string != *b"null" {
Err(JsonError::InvalidValue)?;
}
SingleStepResult::Unknown(SingleStepUnknownResult::Null)
}
};
advance_past_comma_or_to_close(reader)?;
Ok(result)
}
}
}
pub struct Deserializer<'read, R: Read<'read>, S: Stack> {
pub(crate) reader: PeekableRead<'read, R>,
stack: S,
pub(crate) error: Option<JsonError<'read, R, S>>,
}
impl<'read, R: Read<'read>, S: Stack> Deserializer<'read, R, S> {
#[inline(always)]
pub(super) fn single_step(&mut self) -> Result<SingleStepResult, JsonError<'read, R, S>> {
if let Some(e) = self.error {
Err(e)?;
}
let res = single_step(&mut self.reader, &mut self.stack);
if let Some(e) = res.as_ref().err() {
self.error = Some(*e);
}
res
}
}
pub struct Value<'read, 'parent, R: Read<'read>, S: Stack> {
pub(crate) deserializer: Option<&'parent mut Deserializer<'read, R, S>>,
}
impl<'read, 'parent, R: Read<'read>, S: Stack> Drop for Value<'read, 'parent, R, S> {
fn drop(&mut self) {
if let Some(deserializer) = self.deserializer.take() {
if deserializer.error.is_some() {
return;
}
let Some(current) = deserializer.stack.peek() else {
deserializer.error = Some(JsonError::InternalError);
return;
};
let mut depth = match current {
State::Object | State::Array => 1,
State::Unknown => {
let step = match deserializer.single_step() {
Ok(SingleStepResult::Unknown(step)) => step,
Ok(_) => {
deserializer.error = Some(JsonError::InternalError);
return;
}
Err(_) => return,
};
match step {
SingleStepUnknownResult::Number(_) |
SingleStepUnknownResult::Bool(_) |
SingleStepUnknownResult::Null => return,
SingleStepUnknownResult::String => {
handle_string_value(deserializer);
return;
}
SingleStepUnknownResult::ObjectOpened | SingleStepUnknownResult::ArrayOpened => 1,
}
}
};
while depth != 0 {
let Ok(step) = deserializer.single_step() else { return };
match step {
SingleStepResult::Unknown(SingleStepUnknownResult::String) => {
handle_string_value(deserializer);
}
SingleStepResult::Object(SingleStepObjectResult::Field) => {
handle_field(deserializer);
}
SingleStepResult::Object(SingleStepObjectResult::Closed) |
SingleStepResult::Array(SingleStepArrayResult::Closed) => depth -= 1,
SingleStepResult::Unknown(
SingleStepUnknownResult::ObjectOpened | SingleStepUnknownResult::ArrayOpened,
) => depth += 1,
_ => {}
}
}
}
}
}
impl<'read, R: Read<'read>, S: Stack> Deserializer<'read, R, S> {
#[inline(always)]
pub fn new(reader: R) -> Result<Self, JsonError<'read, R, S>> {
let mut reader = PeekableRead::try_from(reader).map_err(JsonError::ReadError)?;
advance_whitespace(&mut reader)?;
let mut stack = S::empty();
stack.push(State::Unknown).map_err(JsonError::StackError)?;
Ok(Deserializer { reader, stack, error: None })
}
#[inline(always)]
pub fn value(&mut self) -> Result<Value<'read, '_, R, S>, JsonError<'read, R, S>> {
if (self.stack.depth() != 1) || self.error.is_some() {
Err(JsonError::ReusedDeserializer)?;
}
let mut result = Value { deserializer: Some(self) };
if !matches!(result.kind()?, Type::Object | Type::Array) {
Err(JsonError::TypeError)?;
}
Ok(result)
}
}