use std::{error::Error, io::Read, str::FromStr};
use self::{
error_safe_reader::ErrorSafeJsonReader,
multi_json_path::{MultiJsonPath, MultiJsonPathPiece},
};
use crate::{
reader::{
JsonReader, JsonReaderPosition, JsonStreamReader, JsonSyntaxError, ReaderError,
SyntaxErrorKind, TransferError, ValueType,
json_path::{JsonPath, JsonPathPiece},
simple::error_safe_reader::create_dummy_error,
},
utf8,
writer::JsonWriter,
};
pub mod multi_json_path {
pub type MultiJsonPath = [MultiJsonPathPiece];
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum MultiJsonPathPiece {
ArrayItem(u32),
AllArrayItems {
allow_empty: bool,
},
ObjectMember(String),
OptionalObjectMember(String),
AllObjectMembers {
allow_empty: bool,
},
}
impl From<u32> for MultiJsonPathPiece {
fn from(v: u32) -> Self {
MultiJsonPathPiece::ArrayItem(v)
}
}
impl From<String> for MultiJsonPathPiece {
fn from(v: String) -> Self {
MultiJsonPathPiece::ObjectMember(v)
}
}
impl From<&str> for MultiJsonPathPiece {
fn from(v: &str) -> Self {
MultiJsonPathPiece::ObjectMember(v.to_string())
}
}
#[doc(hidden)]
pub trait __IntoString {
fn into_string(self) -> String;
}
impl __IntoString for String {
fn into_string(self) -> String {
self
}
}
impl __IntoString for &str {
fn into_string(self) -> String {
self.to_owned()
}
}
#[doc(hidden)]
#[macro_export] macro_rules! __multi_json_path_impl {
( [$($pieces:expr,)*] [*] $($rest:tt)* ) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::AllArrayItems { allow_empty: true }] $($rest)*
)
};
( [$($pieces:expr,)*] [+] $($rest:tt)* ) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::AllArrayItems { allow_empty: false }] $($rest)*
)
};
( [$($pieces:expr,)*] {*} $($rest:tt)* ) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::AllObjectMembers { allow_empty: true }] $($rest)*
)
};
( [$($pieces:expr,)*] {+} $($rest:tt)* ) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::AllObjectMembers { allow_empty: false }] $($rest)*
)
};
( [$($pieces:expr,)*] ?$piece:expr, $($rest:tt)* ) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::OptionalObjectMember($crate::reader::simple::multi_json_path::__IntoString::into_string($piece)),] $($rest)*
)
};
( [$($pieces:expr,)*] ?$piece:expr) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::OptionalObjectMember($crate::reader::simple::multi_json_path::__IntoString::into_string($piece)),]
)
};
( [$($pieces:expr,)*] $piece:expr, $($rest:tt)* ) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::from($piece),] $($rest)*
)
};
( [$($pieces:expr,)*] $piece:expr) => {
$crate::__multi_json_path_impl!(
[$($pieces,)* $crate::reader::simple::multi_json_path::MultiJsonPathPiece::from($piece),]
)
};
( [$($pieces:expr),+] , $($rest:tt)*) => {
$crate::__multi_json_path_impl!(
[$($pieces),+ ,] $($rest)*
)
};
( [] ) => {
[] as [$crate::reader::simple::multi_json_path::MultiJsonPathPiece; 0]
};
( [$($pieces:expr),+ $(,)?] ) => {
[$($pieces),+]
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __multi_json_path {
( $($path:tt)* ) => {
$crate::__multi_json_path_impl!([] $($path)*)
};
}
#[doc(inline)]
pub use __multi_json_path as multi_json_path;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn macro_multi_json_path() {
assert_eq!(multi_json_path![], []);
assert_ne!(
multi_json_path![],
&[MultiJsonPathPiece::ArrayItem(1)] as &MultiJsonPath
);
assert_eq!(multi_json_path![3], [MultiJsonPathPiece::ArrayItem(3)]);
assert_eq!(
multi_json_path![3],
&[MultiJsonPathPiece::ArrayItem(3)] as &MultiJsonPath
);
assert_eq!(
multi_json_path!["a"],
[MultiJsonPathPiece::ObjectMember("a".to_owned())]
);
assert_eq!(
multi_json_path!["a".to_owned()],
[MultiJsonPathPiece::ObjectMember("a".to_owned())]
);
assert_eq!(
multi_json_path!["a",],
[MultiJsonPathPiece::ObjectMember("a".to_owned())]
);
assert_eq!(
multi_json_path!["a", 1,],
[
MultiJsonPathPiece::ObjectMember("a".to_owned()),
MultiJsonPathPiece::ArrayItem(1),
]
);
assert_eq!(
multi_json_path!["outer", 1, "inner".to_owned(), 2],
[
MultiJsonPathPiece::ObjectMember("outer".to_owned()),
MultiJsonPathPiece::ArrayItem(1),
MultiJsonPathPiece::ObjectMember("inner".to_owned()),
MultiJsonPathPiece::ArrayItem(2),
]
);
assert_eq!(
multi_json_path![?"a"],
[MultiJsonPathPiece::OptionalObjectMember("a".to_owned())]
);
assert_eq!(
multi_json_path![?"a".to_owned()],
[MultiJsonPathPiece::OptionalObjectMember("a".to_owned())]
);
assert_eq!(
multi_json_path![?"a",],
[MultiJsonPathPiece::OptionalObjectMember("a".to_owned())]
);
assert_eq!(
multi_json_path![?"a", "b"],
[
MultiJsonPathPiece::OptionalObjectMember("a".to_owned()),
MultiJsonPathPiece::ObjectMember("b".to_owned()),
]
);
assert_eq!(
multi_json_path![[*]],
[MultiJsonPathPiece::AllArrayItems { allow_empty: true }]
);
assert_eq!(
multi_json_path![[*],],
[MultiJsonPathPiece::AllArrayItems { allow_empty: true }]
);
assert_eq!(
multi_json_path![1, [*]],
[
MultiJsonPathPiece::ArrayItem(1),
MultiJsonPathPiece::AllArrayItems { allow_empty: true },
]
);
assert_eq!(
multi_json_path![1, [*],],
[
MultiJsonPathPiece::ArrayItem(1),
MultiJsonPathPiece::AllArrayItems { allow_empty: true },
]
);
assert_eq!(
multi_json_path![1, [*], 1],
[
MultiJsonPathPiece::ArrayItem(1),
MultiJsonPathPiece::AllArrayItems { allow_empty: true },
MultiJsonPathPiece::ArrayItem(1),
]
);
assert_eq!(
multi_json_path![[+]],
[MultiJsonPathPiece::AllArrayItems { allow_empty: false }]
);
assert_eq!(
multi_json_path![{*}],
[MultiJsonPathPiece::AllObjectMembers { allow_empty: true }]
);
assert_eq!(
multi_json_path![{*},],
[MultiJsonPathPiece::AllObjectMembers { allow_empty: true }]
);
assert_eq!(
multi_json_path![1, {*}],
[
MultiJsonPathPiece::ArrayItem(1),
MultiJsonPathPiece::AllObjectMembers { allow_empty: true },
]
);
assert_eq!(
multi_json_path![1, {*},],
[
MultiJsonPathPiece::ArrayItem(1),
MultiJsonPathPiece::AllObjectMembers { allow_empty: true },
]
);
assert_eq!(
multi_json_path![1, {*}, 1],
[
MultiJsonPathPiece::ArrayItem(1),
MultiJsonPathPiece::AllObjectMembers { allow_empty: true },
MultiJsonPathPiece::ArrayItem(1),
]
);
assert_eq!(
multi_json_path![{+}],
[MultiJsonPathPiece::AllObjectMembers { allow_empty: false }]
);
assert_eq!(
multi_json_path![[*], [+], {*}, {+}, 1],
[
MultiJsonPathPiece::AllArrayItems { allow_empty: true },
MultiJsonPathPiece::AllArrayItems { allow_empty: false },
MultiJsonPathPiece::AllObjectMembers { allow_empty: true },
MultiJsonPathPiece::AllObjectMembers { allow_empty: false },
MultiJsonPathPiece::ArrayItem(1),
]
);
}
}
}
pub trait ValueReader<J: JsonReader> {
fn peek_value(&mut self) -> Result<ValueType, ReaderError>;
fn read_null(self) -> Result<(), ReaderError>;
fn read_bool(self) -> Result<bool, ReaderError>;
fn read_str<T>(
self,
f: impl FnOnce(&str) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>>;
fn read_string(self) -> Result<String, ReaderError>;
fn read_string_with_reader<T>(
self,
f: impl FnOnce(StringValueReader<'_>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>>;
fn read_number<T: FromStr>(self) -> Result<Result<T, T::Err>, ReaderError>;
fn read_number_as_string(self) -> Result<String, ReaderError>;
#[cfg(feature = "serde")]
fn read_deserialize<'de, D: serde_core::de::Deserialize<'de>>(
self,
) -> Result<D, crate::serde::DeserializerError>;
fn skip_value(self) -> Result<(), ReaderError>;
fn read_array<T>(
self,
f: impl FnOnce(&mut ArrayReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>>;
fn read_array_items(
self,
mut f: impl FnMut(SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>>
where
Self: Sized,
{
self.read_array(|array_reader| {
while array_reader.has_next()? {
read_value(array_reader.json_reader, &mut f)?;
}
Ok(())
})
}
fn read_object_borrowed_names(
self,
f: impl FnMut(MemberReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>>;
fn read_object_owned_names(
self,
f: impl FnMut(String, SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>>;
fn read_seeked<T>(
self,
path: &JsonPath,
f: impl FnOnce(SingleValueReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>>;
fn read_seeked_multi(
self,
path: &MultiJsonPath,
at_least_one_match: bool,
f: impl FnMut(SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>>;
}
fn read_array<J: JsonReader, T>(
json_reader: &mut ErrorSafeJsonReader<J>,
f: impl FnOnce(&mut ArrayReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
json_reader.begin_array()?;
let mut array_reader = ArrayReader { json_reader };
let result = f(&mut array_reader)?;
json_reader.end_array()?;
Ok(result)
}
fn read_object_borrowed_names<J: JsonReader>(
json_reader: &mut ErrorSafeJsonReader<J>,
mut f: impl FnMut(MemberReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
json_reader.begin_object()?;
while json_reader.has_next()? {
let mut consumed_name = false;
let mut consumed_value = false;
let member_reader = MemberReader {
json_reader,
consumed_name: &mut consumed_name,
consumed_value: &mut consumed_value,
};
f(member_reader)?;
if !consumed_name {
json_reader.skip_name()?;
}
if !consumed_value {
json_reader.skip_value()?;
}
}
json_reader.end_object()?;
Ok(())
}
fn read_object_owned_names<J: JsonReader>(
json_reader: &mut ErrorSafeJsonReader<J>,
mut f: impl FnMut(String, SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
json_reader.begin_object()?;
while json_reader.has_next()? {
let name = json_reader.next_name_owned()?;
let mut consumed_value = false;
let member_value_reader = SingleValueReader {
json_reader,
consumed_value: &mut consumed_value,
};
f(name, member_value_reader)?;
if !consumed_value {
json_reader.skip_value()?;
}
}
json_reader.end_object()?;
Ok(())
}
fn read_string_with_reader<J: JsonReader, T>(
json_reader: &mut ErrorSafeJsonReader<J>,
f: impl FnOnce(StringValueReader<'_>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
let mut delegate = json_reader.next_string_reader()?;
let string_reader: StringValueReader<'_> = StringValueReader {
delegate: &mut delegate as &mut dyn Read,
};
let result = f(string_reader)?;
if let Some(error) = delegate.error {
return Err(error.rough_clone().into());
}
if delegate.read(&mut [0_u8; utf8::MAX_BYTES_PER_CHAR])? > 0 {
let mut buf = [0_u8; 512];
while delegate.read(&mut buf)? > 0 {
}
}
Ok(result)
}
fn read_value<J: JsonReader, T>(
json_reader: &mut ErrorSafeJsonReader<J>,
f: impl FnOnce(SingleValueReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
let mut consumed_value = false;
let value_reader = SingleValueReader {
json_reader,
consumed_value: &mut consumed_value,
};
let result = f(value_reader)?;
if !consumed_value {
json_reader.skip_value()?;
}
Ok(result)
}
fn read_seeked<J: JsonReader, T>(
json_reader: &mut ErrorSafeJsonReader<J>,
path: &JsonPath,
f: impl FnOnce(SingleValueReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
json_reader.seek_to(path)?;
let result = read_value(json_reader, f)?;
json_reader.seek_back(path)?;
Ok(result)
}
fn read_seeked_multi<J: JsonReader>(
json_reader: &mut ErrorSafeJsonReader<J>,
original_path: &MultiJsonPath,
require_at_least_one_match: bool,
mut f: impl FnMut(SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
if original_path.is_empty() {
return read_value(json_reader, &mut f);
}
enum PartialPath {
JsonPath(Vec<JsonPathPiece>),
AllArrayItems { allow_empty: bool },
OptionalObjectMember(String),
AllObjectMembers { allow_empty: bool },
}
fn convert_path(path: &MultiJsonPath) -> Vec<PartialPath> {
let mut converted_path = Vec::<PartialPath>::new();
let mut current_section = None;
for piece in path {
match piece {
MultiJsonPathPiece::ArrayItem(index) => {
let current_section = current_section.get_or_insert_with(Vec::new);
current_section.push(JsonPathPiece::ArrayItem(*index));
}
MultiJsonPathPiece::ObjectMember(name) => {
let current_section = current_section.get_or_insert_with(Vec::new);
current_section.push(JsonPathPiece::ObjectMember(name.clone()));
}
MultiJsonPathPiece::AllArrayItems { allow_empty } => {
if let Some(current_section) = current_section.take() {
converted_path.push(PartialPath::JsonPath(current_section));
}
converted_path.push(PartialPath::AllArrayItems {
allow_empty: *allow_empty,
});
}
MultiJsonPathPiece::OptionalObjectMember(name) => {
if let Some(current_section) = current_section.take() {
converted_path.push(PartialPath::JsonPath(current_section));
}
converted_path.push(PartialPath::OptionalObjectMember(name.clone()));
}
MultiJsonPathPiece::AllObjectMembers { allow_empty } => {
if let Some(current_section) = current_section.take() {
converted_path.push(PartialPath::JsonPath(current_section));
}
converted_path.push(PartialPath::AllObjectMembers {
allow_empty: *allow_empty,
});
}
}
}
if let Some(current_section) = current_section {
converted_path.push(PartialPath::JsonPath(current_section));
}
converted_path
}
let original_location = if require_at_least_one_match {
Some(json_reader.current_position(true))
} else {
None
};
let path = convert_path(original_path);
let mut path_index = 0;
let mut has_match = false;
let mut is_moving_down = true;
loop {
match &path[path_index] {
PartialPath::JsonPath(path) => {
if is_moving_down {
json_reader.seek_to(path)?;
path_index += 1;
} else {
json_reader.seek_back(path)?;
}
}
PartialPath::AllArrayItems { allow_empty } => {
if is_moving_down {
json_reader.begin_array()?;
if !allow_empty && !json_reader.has_next()? {
return Err(json_reader
.peek()
.expect_err("should have failed with `FewerElementsThanExpected`")
.into());
}
}
if json_reader.has_next()? {
is_moving_down = true;
path_index += 1;
} else {
json_reader.end_array()?;
is_moving_down = false;
}
}
PartialPath::OptionalObjectMember(name) => {
if is_moving_down {
json_reader.begin_object()?;
let mut found_member = false;
while json_reader.has_next()? {
if json_reader.next_name()? == name {
found_member = true;
path_index += 1;
break;
} else {
json_reader.skip_value()?;
}
}
if !found_member {
json_reader.end_object()?;
is_moving_down = false;
}
} else {
while json_reader.has_next()? {
json_reader.skip_name()?;
json_reader.skip_value()?;
}
json_reader.end_object()?;
}
}
PartialPath::AllObjectMembers { allow_empty } => {
if is_moving_down {
json_reader.begin_object()?;
if !allow_empty && !json_reader.has_next()? {
return Err(json_reader
.skip_name()
.expect_err("should have failed with `FewerElementsThanExpected`")
.into());
}
}
if json_reader.has_next()? {
json_reader.skip_name()?;
is_moving_down = true;
path_index += 1;
} else {
json_reader.end_object()?;
is_moving_down = false;
}
}
}
if is_moving_down && path_index >= path.len() {
has_match = true;
read_value(json_reader, &mut f)?;
match path[path_index - 1] {
PartialPath::JsonPath(_) | PartialPath::OptionalObjectMember(_) => {}
PartialPath::AllArrayItems { .. } => {
while json_reader.has_next()? {
read_value(json_reader, &mut f)?;
}
}
PartialPath::AllObjectMembers { .. } => {
while json_reader.has_next()? {
json_reader.skip_name()?;
read_value(json_reader, &mut f)?;
}
}
}
is_moving_down = false;
}
if !is_moving_down {
if path_index == 0 {
break;
}
path_index -= 1;
}
}
if require_at_least_one_match && !has_match {
let formatted_path = original_path
.iter()
.map(|p| match p {
MultiJsonPathPiece::ArrayItem(index) => format!("[{index}]"),
MultiJsonPathPiece::AllArrayItems { allow_empty } => {
if *allow_empty { "[*]" } else { "[+]" }.to_owned()
}
MultiJsonPathPiece::ObjectMember(name) => format!(".{name}"),
MultiJsonPathPiece::OptionalObjectMember(name) => format!(".{name}?"),
MultiJsonPathPiece::AllObjectMembers { allow_empty } => {
if *allow_empty { ".*" } else { ".+" }.to_owned()
}
})
.collect::<String>();
let original_location = original_location.unwrap();
if json_reader.error.is_none() {
json_reader.error = Some(create_dummy_error(&original_location));
}
Err(
format!("no matching value found for path '{formatted_path}' at {original_location}")
.into(),
)
} else {
Ok(())
}
}
mod error_safe_reader {
use super::*;
type IoError = std::io::Error;
pub(super) fn clone_original_io_error(error: &IoError) -> IoError {
#[expect(
clippy::to_string_in_format_args,
reason = "make it explicit that this uses `to_string()`"
)]
IoError::other(format!(
"previous error '{}': {}",
error.kind(),
error.to_string()
))
}
pub(super) fn create_dummy_error(location: &JsonReaderPosition) -> ReaderError {
ReaderError::SyntaxError(JsonSyntaxError {
kind: SyntaxErrorKind::IncompleteDocument,
location: location.clone(),
})
}
fn create_unknown_pos_error() -> ReaderError {
create_dummy_error(&JsonReaderPosition::unknown_position())
}
macro_rules! use_delegate {
($self:ident, |$json_reader:ident| $reading_action:expr, |$original_error:ident| $original_error_converter:expr, |$stored_error:ident| $stored_error_converter:expr) => {
if let Some(error) = &$self.error {
let $stored_error = error.rough_clone();
Err($stored_error_converter)
} else {
let $json_reader = &mut $self.delegate;
let result = $reading_action;
if let Err($original_error) = &result {
$self.error = Some($original_error_converter);
}
result
}
};
($self:ident, |$json_reader:ident| $reading_action:expr) => {
use_delegate!(
$self,
|$json_reader| $reading_action,
|original_error| {
match original_error {
e @ ReaderError::SyntaxError(_) => e.rough_clone(),
e @ ReaderError::MaxNestingDepthExceeded { .. } => e.rough_clone(),
e @ ReaderError::UnsupportedNumberValue { .. } => e.rough_clone(),
ReaderError::IoError { error, location } => ReaderError::IoError {
error: clone_original_io_error(error),
location: location.clone(),
},
ReaderError::UnexpectedValueType { location, .. } => create_dummy_error(location),
ReaderError::UnexpectedStructure { location, .. } => create_dummy_error(location),
}
},
|stored_error| stored_error
)
};
}
#[derive(Debug)]
pub(super) struct ErrorSafeJsonReader<J: JsonReader> {
pub(super) delegate: J,
pub(super) error: Option<ReaderError>,
}
impl<J: JsonReader> JsonReader for ErrorSafeJsonReader<J> {
fn peek(&mut self) -> Result<ValueType, ReaderError> {
use_delegate!(self, |r| r.peek())
}
fn begin_object(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.begin_object())
}
fn end_object(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.end_object())
}
fn begin_array(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.begin_array())
}
fn end_array(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.end_array())
}
fn has_next(&mut self) -> Result<bool, ReaderError> {
use_delegate!(self, |r| r.has_next())
}
fn next_name(&mut self) -> Result<&str, ReaderError> {
use_delegate!(self, |r| r.next_name())
}
fn next_name_owned(&mut self) -> Result<String, ReaderError> {
use_delegate!(self, |r| r.next_name_owned())
}
fn next_str(&mut self) -> Result<&str, ReaderError> {
use_delegate!(self, |r| r.next_str())
}
fn next_string(&mut self) -> Result<String, ReaderError> {
use_delegate!(self, |r| r.next_string())
}
#[expect(
refining_impl_trait,
reason = "this `JsonReader` impl is for an internal struct, so should not cause issues?"
)]
fn next_string_reader(
&mut self,
) -> Result<ErrorSafeStringValueReader<'_, impl Read>, ReaderError> {
let string_reader_delegate = use_delegate!(self, |r| r.next_string_reader())?;
Ok(ErrorSafeStringValueReader {
delegate: string_reader_delegate,
error: &mut self.error,
})
}
fn next_number_as_str(&mut self) -> Result<&str, ReaderError> {
use_delegate!(self, |r| r.next_number_as_str())
}
fn next_number_as_string(&mut self) -> Result<String, ReaderError> {
use_delegate!(self, |r| r.next_number_as_string())
}
fn next_number<T: FromStr>(&mut self) -> Result<Result<T, T::Err>, ReaderError> {
use_delegate!(self, |r| r.next_number())
}
fn next_bool(&mut self) -> Result<bool, ReaderError> {
use_delegate!(self, |r| r.next_bool())
}
fn next_null(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.next_null())
}
#[cfg(feature = "serde")]
fn deserialize_next<'de, D: serde_core::de::Deserialize<'de>>(
&mut self,
) -> Result<D, crate::serde::DeserializerError> {
use crate::serde::DeserializerError;
use_delegate!(
self,
|r| r.deserialize_next(),
|original_error| {
match original_error {
DeserializerError::ReaderError(e) => e.rough_clone(),
DeserializerError::Custom(_) => create_unknown_pos_error(),
DeserializerError::MaxNestingDepthExceeded(_) => create_unknown_pos_error(),
DeserializerError::InvalidNumber(_) => create_unknown_pos_error(),
}
},
|stored_error| DeserializerError::ReaderError(stored_error)
)
}
fn skip_name(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.skip_name())
}
fn skip_value(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.skip_value())
}
fn skip_to_top_level(&mut self) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.skip_to_top_level())
}
fn transfer_to<W: JsonWriter>(&mut self, json_writer: &mut W) -> Result<(), TransferError> {
use_delegate!(
self,
|r| r.transfer_to(json_writer),
|original_error| match original_error {
TransferError::ReaderError(e) => e.rough_clone(),
TransferError::WriterError(_) => create_unknown_pos_error(),
},
|stored_error| TransferError::ReaderError(stored_error)
)
}
fn current_position(&self, include_path: bool) -> JsonReaderPosition {
self.delegate.current_position(include_path)
}
fn seek_to(&mut self, rel_json_path: &JsonPath) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.seek_to(rel_json_path))
}
fn seek_back(&mut self, rel_json_path: &JsonPath) -> Result<(), ReaderError> {
use_delegate!(self, |r| r.seek_back(rel_json_path))
}
fn consume_trailing_whitespace(self) -> Result<(), ReaderError> {
if let Some(error) = self.error {
return Err(error);
}
self.delegate.consume_trailing_whitespace()
}
}
pub(super) struct ErrorSafeStringValueReader<'a, D: Read> {
delegate: D,
pub(super) error: &'a mut Option<ReaderError>,
}
impl<D: Read> ErrorSafeStringValueReader<'_, D> {
fn use_delegate<T>(
&mut self,
f: impl FnOnce(&mut D) -> std::io::Result<T>,
) -> std::io::Result<T> {
if let Some(error) = &self.error {
return Err(match error.rough_clone() {
ReaderError::IoError { error, .. } => error,
e => unreachable!("unexpected error type: {e:?}"),
});
}
let result = f(&mut self.delegate);
if let Err(error) = &result {
*self.error = Some(ReaderError::IoError {
error: clone_original_io_error(error),
location: JsonReaderPosition::unknown_position(),
});
}
result
}
}
impl<D: Read> Read for ErrorSafeStringValueReader<'_, D> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.use_delegate(|d| d.read(buf))
}
}
}
#[derive(Debug)]
pub struct SimpleJsonReader<J: JsonReader> {
json_reader: ErrorSafeJsonReader<J>,
has_seeked: bool,
}
impl<J: JsonReader> SimpleJsonReader<J> {
pub fn from_json_reader(json_reader: J) -> Self {
SimpleJsonReader {
json_reader: ErrorSafeJsonReader {
delegate: json_reader,
error: None,
},
has_seeked: false,
}
}
pub fn seek_to(&mut self, path: &JsonPath) -> Result<(), ReaderError> {
self.has_seeked = true;
self.json_reader.seek_to(path)
}
fn finish(mut self) -> Result<(), ReaderError> {
if self.has_seeked {
self.json_reader.skip_to_top_level()?;
}
self.json_reader.consume_trailing_whitespace()
}
}
impl<R: Read> SimpleJsonReader<JsonStreamReader<R>> {
pub fn new(reader: R) -> Self {
SimpleJsonReader::from_json_reader(JsonStreamReader::new(reader))
}
}
impl<J: JsonReader> ValueReader<J> for SimpleJsonReader<J> {
fn peek_value(&mut self) -> Result<ValueType, ReaderError> {
self.json_reader.peek()
}
fn read_null(mut self) -> Result<(), ReaderError> {
self.json_reader.next_null()?;
self.finish()
}
fn read_bool(mut self) -> Result<bool, ReaderError> {
let result = self.json_reader.next_bool()?;
self.finish()?;
Ok(result)
}
fn read_str<T>(
mut self,
f: impl FnOnce(&str) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
let result = f(self.json_reader.next_str()?)?;
self.finish()?;
Ok(result)
}
fn read_string(mut self) -> Result<String, ReaderError> {
let result = self.json_reader.next_string()?;
self.finish()?;
Ok(result)
}
fn read_string_with_reader<T>(
mut self,
f: impl FnOnce(StringValueReader<'_>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
let result = read_string_with_reader(&mut self.json_reader, f)?;
self.finish()?;
Ok(result)
}
fn read_number<T: FromStr>(mut self) -> Result<Result<T, T::Err>, ReaderError> {
let result = self.json_reader.next_number()?;
self.finish()?;
Ok(result)
}
fn read_number_as_string(mut self) -> Result<String, ReaderError> {
let result = self.json_reader.next_number_as_string()?;
self.finish()?;
Ok(result)
}
#[cfg(feature = "serde")]
fn read_deserialize<'de, D: serde_core::de::Deserialize<'de>>(
mut self,
) -> Result<D, crate::serde::DeserializerError> {
let result = self.json_reader.deserialize_next()?;
self.finish()?;
Ok(result)
}
fn skip_value(mut self) -> Result<(), ReaderError> {
self.json_reader.skip_value()?;
self.finish()
}
fn read_array<T>(
mut self,
f: impl FnOnce(&mut ArrayReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
let result = read_array(&mut self.json_reader, f)?;
self.finish()?;
Ok(result)
}
fn read_object_borrowed_names(
mut self,
f: impl FnMut(MemberReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
read_object_borrowed_names(&mut self.json_reader, f)?;
self.finish()?;
Ok(())
}
fn read_object_owned_names(
mut self,
f: impl FnMut(String, SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
read_object_owned_names(&mut self.json_reader, f)?;
self.finish()?;
Ok(())
}
fn read_seeked<T>(
mut self,
path: &JsonPath,
f: impl FnOnce(SingleValueReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
let result = read_seeked(&mut self.json_reader, path, f)?;
self.finish()?;
Ok(result)
}
fn read_seeked_multi(
mut self,
path: &MultiJsonPath,
at_least_one_match: bool,
f: impl FnMut(SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
read_seeked_multi(&mut self.json_reader, path, at_least_one_match, f)?;
self.finish()?;
Ok(())
}
}
#[derive(Debug)]
pub struct ArrayReader<'a, J: JsonReader> {
json_reader: &'a mut ErrorSafeJsonReader<J>,
}
impl<J: JsonReader> ArrayReader<'_, J> {
pub fn has_next(&mut self) -> Result<bool, ReaderError> {
self.json_reader.has_next()
}
}
impl<J: JsonReader> ValueReader<J> for &mut ArrayReader<'_, J> {
fn peek_value(&mut self) -> Result<ValueType, ReaderError> {
self.json_reader.peek()
}
fn read_null(self) -> Result<(), ReaderError> {
self.json_reader.next_null()
}
fn read_bool(self) -> Result<bool, ReaderError> {
self.json_reader.next_bool()
}
fn read_str<T>(
self,
f: impl FnOnce(&str) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
f(self.json_reader.next_str()?)
}
fn read_string(self) -> Result<String, ReaderError> {
self.json_reader.next_string()
}
fn read_string_with_reader<T>(
self,
f: impl FnOnce(StringValueReader<'_>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
read_string_with_reader(self.json_reader, f)
}
fn read_number<T: FromStr>(self) -> Result<Result<T, T::Err>, ReaderError> {
self.json_reader.next_number()
}
fn read_number_as_string(self) -> Result<String, ReaderError> {
self.json_reader.next_number_as_string()
}
#[cfg(feature = "serde")]
fn read_deserialize<'de, D: serde_core::de::Deserialize<'de>>(
self,
) -> Result<D, crate::serde::DeserializerError> {
self.json_reader.deserialize_next()
}
fn skip_value(self) -> Result<(), ReaderError> {
self.json_reader.skip_value()
}
fn read_array<T>(
self,
f: impl FnOnce(&mut ArrayReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
read_array(self.json_reader, f)
}
fn read_object_borrowed_names(
self,
f: impl FnMut(MemberReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
read_object_borrowed_names(self.json_reader, f)
}
fn read_object_owned_names(
self,
f: impl FnMut(String, SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
read_object_owned_names(self.json_reader, f)
}
fn read_seeked<T>(
self,
path: &JsonPath,
f: impl FnOnce(SingleValueReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
read_seeked(self.json_reader, path, f)
}
fn read_seeked_multi(
self,
path: &MultiJsonPath,
at_least_one_match: bool,
f: impl FnMut(SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
read_seeked_multi(self.json_reader, path, at_least_one_match, f)
}
}
#[derive(Debug)]
pub struct SingleValueReader<'a, J: JsonReader> {
json_reader: &'a mut ErrorSafeJsonReader<J>,
consumed_value: &'a mut bool,
}
impl<J: JsonReader> ValueReader<J> for SingleValueReader<'_, J> {
fn peek_value(&mut self) -> Result<ValueType, ReaderError> {
self.json_reader.peek()
}
fn read_null(self) -> Result<(), ReaderError> {
*self.consumed_value = true;
self.json_reader.next_null()
}
fn read_bool(self) -> Result<bool, ReaderError> {
*self.consumed_value = true;
self.json_reader.next_bool()
}
fn read_str<T>(
self,
f: impl FnOnce(&str) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
*self.consumed_value = true;
f(self.json_reader.next_str()?)
}
fn read_string(self) -> Result<String, ReaderError> {
*self.consumed_value = true;
self.json_reader.next_string()
}
fn read_string_with_reader<T>(
self,
f: impl FnOnce(StringValueReader<'_>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
*self.consumed_value = true;
read_string_with_reader(self.json_reader, f)
}
fn read_number<T: FromStr>(self) -> Result<Result<T, T::Err>, ReaderError> {
*self.consumed_value = true;
self.json_reader.next_number()
}
fn read_number_as_string(self) -> Result<String, ReaderError> {
*self.consumed_value = true;
self.json_reader.next_number_as_string()
}
#[cfg(feature = "serde")]
fn read_deserialize<'de, D: serde_core::de::Deserialize<'de>>(
self,
) -> Result<D, crate::serde::DeserializerError> {
*self.consumed_value = true;
self.json_reader.deserialize_next()
}
fn skip_value(self) -> Result<(), ReaderError> {
*self.consumed_value = true;
self.json_reader.skip_value()
}
fn read_array<T>(
self,
f: impl FnOnce(&mut ArrayReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
*self.consumed_value = true;
read_array(self.json_reader, f)
}
fn read_object_borrowed_names(
self,
f: impl FnMut(MemberReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
*self.consumed_value = true;
read_object_borrowed_names(self.json_reader, f)
}
fn read_object_owned_names(
self,
f: impl FnMut(String, SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
*self.consumed_value = true;
read_object_owned_names(self.json_reader, f)
}
fn read_seeked<T>(
self,
path: &JsonPath,
f: impl FnOnce(SingleValueReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
*self.consumed_value = true;
read_seeked(self.json_reader, path, f)
}
fn read_seeked_multi(
self,
path: &MultiJsonPath,
at_least_one_match: bool,
f: impl FnMut(SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
*self.consumed_value = true;
read_seeked_multi(self.json_reader, path, at_least_one_match, f)
}
}
#[derive(Debug)]
pub struct MemberReader<'a, J: JsonReader> {
json_reader: &'a mut ErrorSafeJsonReader<J>,
consumed_name: &'a mut bool,
consumed_value: &'a mut bool,
}
impl<J: JsonReader> MemberReader<'_, J> {
pub fn read_name(&mut self) -> Result<&str, ReaderError> {
if *self.consumed_name {
panic!("name has already been consumed");
}
*self.consumed_name = true;
self.json_reader.next_name()
}
fn check_skip_name(&mut self) -> Result<(), ReaderError> {
if !*self.consumed_name {
*self.consumed_name = true;
self.json_reader.skip_name()?;
}
Ok(())
}
}
impl<J: JsonReader> ValueReader<J> for MemberReader<'_, J> {
fn peek_value(&mut self) -> Result<ValueType, ReaderError> {
self.check_skip_name()?;
self.json_reader.peek()
}
fn read_null(mut self) -> Result<(), ReaderError> {
self.check_skip_name()?;
*self.consumed_value = true;
self.json_reader.next_null()
}
fn read_bool(mut self) -> Result<bool, ReaderError> {
self.check_skip_name()?;
*self.consumed_value = true;
self.json_reader.next_bool()
}
fn read_str<T>(
mut self,
f: impl FnOnce(&str) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
self.check_skip_name()?;
*self.consumed_value = true;
f(self.json_reader.next_str()?)
}
fn read_string(mut self) -> Result<String, ReaderError> {
self.check_skip_name()?;
*self.consumed_value = true;
self.json_reader.next_string()
}
fn read_string_with_reader<T>(
mut self,
f: impl FnOnce(StringValueReader<'_>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
self.check_skip_name()?;
*self.consumed_value = true;
read_string_with_reader(self.json_reader, f)
}
fn read_number<T: FromStr>(mut self) -> Result<Result<T, T::Err>, ReaderError> {
self.check_skip_name()?;
*self.consumed_value = true;
self.json_reader.next_number()
}
fn read_number_as_string(mut self) -> Result<String, ReaderError> {
self.check_skip_name()?;
*self.consumed_value = true;
self.json_reader.next_number_as_string()
}
#[cfg(feature = "serde")]
fn read_deserialize<'de, D: serde_core::de::Deserialize<'de>>(
mut self,
) -> Result<D, crate::serde::DeserializerError> {
self.check_skip_name()?;
*self.consumed_value = true;
self.json_reader.deserialize_next()
}
fn skip_value(mut self) -> Result<(), ReaderError> {
self.check_skip_name()?;
*self.consumed_value = true;
self.json_reader.skip_value()
}
fn read_array<T>(
mut self,
f: impl FnOnce(&mut ArrayReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
self.check_skip_name()?;
*self.consumed_value = true;
read_array(self.json_reader, f)
}
fn read_object_borrowed_names(
mut self,
f: impl FnMut(MemberReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
self.check_skip_name()?;
*self.consumed_value = true;
read_object_borrowed_names(self.json_reader, f)
}
fn read_object_owned_names(
mut self,
f: impl FnMut(String, SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
self.check_skip_name()?;
*self.consumed_value = true;
read_object_owned_names(self.json_reader, f)
}
fn read_seeked<T>(
mut self,
path: &JsonPath,
f: impl FnOnce(SingleValueReader<'_, J>) -> Result<T, Box<dyn Error>>,
) -> Result<T, Box<dyn Error>> {
self.check_skip_name()?;
*self.consumed_value = true;
read_seeked(self.json_reader, path, f)
}
fn read_seeked_multi(
mut self,
path: &MultiJsonPath,
at_least_one_match: bool,
f: impl FnMut(SingleValueReader<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
self.check_skip_name()?;
*self.consumed_value = true;
read_seeked_multi(self.json_reader, path, at_least_one_match, f)
}
}
pub struct StringValueReader<'a> {
delegate: &'a mut dyn Read,
}
impl Read for StringValueReader<'_> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.delegate.read(buf)
}
}