use std::{error::Error, io::Write};
use self::error_safe_writer::{ErrorSafeJsonWriter, error_from_stored};
use crate::writer::{
FiniteNumber, FloatingPointNumber, JsonNumberError, JsonStreamWriter, JsonWriter,
StringValueWriter as AdvancedStringValueWriter,
};
type IoError = std::io::Error;
pub trait ValueWriter<J: JsonWriter> {
fn write_null(self) -> Result<(), IoError>;
fn write_bool(self, value: bool) -> Result<(), IoError>;
fn write_string(self, value: &str) -> Result<(), IoError>;
fn write_string_with_writer(
self,
f: impl FnOnce(StringValueWriter<'_>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>>;
fn write_number<N: FiniteNumber>(self, value: N) -> Result<(), IoError>;
fn write_fp_number<N: FloatingPointNumber>(self, value: N) -> Result<(), JsonNumberError>;
fn write_number_string(self, value: &str) -> Result<(), JsonNumberError>;
#[cfg(feature = "serde")]
fn write_serialize<S: serde_core::ser::Serialize>(
self,
value: &S,
) -> Result<(), crate::serde::SerializerError>;
fn write_array(
self,
f: impl FnOnce(&mut ArrayWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>>;
fn write_object(
self,
f: impl FnOnce(&mut ObjectWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>>;
}
fn write_array<J: JsonWriter>(
json_writer: &mut ErrorSafeJsonWriter<J>,
f: impl FnOnce(&mut ArrayWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
json_writer.begin_array()?;
let mut array_writer = ArrayWriter { json_writer };
f(&mut array_writer)?;
json_writer.end_array()?;
Ok(())
}
fn write_object<J: JsonWriter>(
json_writer: &mut ErrorSafeJsonWriter<J>,
f: impl FnOnce(&mut ObjectWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
json_writer.begin_object()?;
let mut object_writer = ObjectWriter { json_writer };
f(&mut object_writer)?;
json_writer.end_object()?;
Ok(())
}
fn write_string_with_writer<J: JsonWriter>(
json_writer: &mut ErrorSafeJsonWriter<J>,
f: impl FnOnce(StringValueWriter<'_>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
let mut delegate = json_writer.string_value_writer()?;
let string_writer = StringValueWriter {
delegate: &mut delegate as &mut dyn AdvancedStringValueWriter,
};
f(string_writer)?;
if let Some(error) = delegate.error {
return Err(error_from_stored(error).into());
}
delegate.finish_value()?;
Ok(())
}
mod error_safe_writer {
use std::io::ErrorKind;
use super::*;
use crate::writer::IoError;
pub(super) type StoredIoError = (ErrorKind, String);
pub(super) fn convert_io_error(error: &IoError) -> StoredIoError {
(error.kind(), error.to_string())
}
fn convert_number_error(error: &JsonNumberError) -> StoredIoError {
match error {
JsonNumberError::InvalidNumber(message) => (ErrorKind::Other, message.clone()),
JsonNumberError::IoError(e) => convert_io_error(e),
}
}
pub(super) fn error_from_stored(error: &StoredIoError) -> IoError {
IoError::other(format!("previous error '{}': {}", error.0, error.1.clone()))
}
macro_rules! use_delegate {
($self:ident, |$json_writer:ident| $writing_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_from_stored(error);
Err($stored_error_converter)
} else {
let $json_writer = &mut $self.delegate;
let result = $writing_action;
if let Err($original_error) = &result {
$self.error = Some($original_error_converter);
}
result
}
};
($self:ident, |$json_writer:ident| $writing_action:expr) => {
use_delegate!(
$self,
|$json_writer| $writing_action,
|original_error| convert_io_error(original_error),
|stored_error| stored_error
)
};
}
#[derive(Debug)]
pub(super) struct ErrorSafeJsonWriter<J: JsonWriter> {
pub(super) delegate: J,
pub(super) error: Option<StoredIoError>,
}
impl<J: JsonWriter> JsonWriter for ErrorSafeJsonWriter<J> {
type WriterResult = J::WriterResult;
fn begin_object(&mut self) -> Result<(), IoError> {
use_delegate!(self, |w| w.begin_object())
}
fn end_object(&mut self) -> Result<(), IoError> {
use_delegate!(self, |w| w.end_object())
}
fn begin_array(&mut self) -> Result<(), IoError> {
use_delegate!(self, |w| w.begin_array())
}
fn end_array(&mut self) -> Result<(), IoError> {
use_delegate!(self, |w| w.end_array())
}
fn name(&mut self, name: &str) -> Result<(), IoError> {
use_delegate!(self, |w| w.name(name))
}
fn null_value(&mut self) -> Result<(), IoError> {
use_delegate!(self, |w| w.null_value())
}
fn bool_value(&mut self, value: bool) -> Result<(), IoError> {
use_delegate!(self, |w| w.bool_value(value))
}
fn string_value(&mut self, value: &str) -> Result<(), IoError> {
use_delegate!(self, |w| w.string_value(value))
}
#[expect(
refining_impl_trait,
reason = "this `JsonWriter` impl is for an internal struct, so should not cause issues?"
)]
fn string_value_writer(
&mut self,
) -> Result<ErrorSafeStringValueWriter<'_, impl AdvancedStringValueWriter>, IoError>
{
let string_writer_delegate = use_delegate!(self, |w| w.string_value_writer())?;
Ok(ErrorSafeStringValueWriter {
delegate: string_writer_delegate,
error: &mut self.error,
})
}
fn number_value_from_string(&mut self, value: &str) -> Result<(), JsonNumberError> {
use_delegate!(
self,
|w| w.number_value_from_string(value),
|original_error| convert_number_error(original_error),
|stored_error| JsonNumberError::IoError(stored_error)
)
}
fn number_value<N: FiniteNumber>(&mut self, value: N) -> Result<(), IoError> {
use_delegate!(self, |w| w.number_value(value))
}
fn fp_number_value<N: FloatingPointNumber>(
&mut self,
value: N,
) -> Result<(), JsonNumberError> {
use_delegate!(
self,
|w| w.fp_number_value(value),
|original_error| convert_number_error(original_error),
|stored_error| JsonNumberError::IoError(stored_error)
)
}
#[cfg(feature = "serde")]
fn serialize_value<S: serde_core::ser::Serialize>(
&mut self,
value: &S,
) -> Result<(), crate::serde::SerializerError> {
use crate::serde::SerializerError;
use_delegate!(
self,
|w| w.serialize_value(value),
|original_error| match original_error {
SerializerError::IoError(e) => convert_io_error(e),
e => (ErrorKind::Other, e.to_string()),
},
|stored_error| SerializerError::IoError(stored_error)
)
}
fn finish_document(self) -> Result<Self::WriterResult, IoError> {
if let Some(error) = self.error {
return Err(error_from_stored(&error));
}
self.delegate.finish_document()
}
}
pub(super) struct ErrorSafeStringValueWriter<'a, D: AdvancedStringValueWriter> {
delegate: D,
pub(super) error: &'a mut Option<StoredIoError>,
}
impl<D: AdvancedStringValueWriter> ErrorSafeStringValueWriter<'_, 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(error_from_stored(error));
}
let result = f(&mut self.delegate);
if let Err(error) = &result {
*self.error = Some(convert_io_error(error));
}
result
}
}
impl<D: AdvancedStringValueWriter> Write for ErrorSafeStringValueWriter<'_, D> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.use_delegate(|d| d.write(buf))
}
fn flush(&mut self) -> std::io::Result<()> {
self.use_delegate(|d| d.flush())
}
}
impl<D: AdvancedStringValueWriter> AdvancedStringValueWriter for ErrorSafeStringValueWriter<'_, D> {
fn write_str(&mut self, s: &str) -> Result<(), IoError> {
self.use_delegate(|d| d.write_str(s))
}
fn finish_value(self) -> Result<(), IoError> {
if let Some(error) = self.error {
return Err(error_from_stored(error));
}
let result = self.delegate.finish_value();
if let Err(error) = &result {
*self.error = Some(convert_io_error(error));
}
result
}
}
}
#[derive(Debug)]
pub struct SimpleJsonWriter<J: JsonWriter> {
json_writer: ErrorSafeJsonWriter<J>,
}
impl<J: JsonWriter> SimpleJsonWriter<J> {
pub fn from_json_writer(json_writer: J) -> Self {
SimpleJsonWriter {
json_writer: ErrorSafeJsonWriter {
delegate: json_writer,
error: None,
},
}
}
}
impl<W: Write> SimpleJsonWriter<JsonStreamWriter<W>> {
pub fn new(writer: W) -> Self {
SimpleJsonWriter::from_json_writer(JsonStreamWriter::new(writer))
}
}
impl<J: JsonWriter> ValueWriter<J> for SimpleJsonWriter<J> {
fn write_null(mut self) -> Result<(), IoError> {
self.json_writer.null_value()?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_bool(mut self, value: bool) -> Result<(), IoError> {
self.json_writer.bool_value(value)?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_string(mut self, value: &str) -> Result<(), IoError> {
self.json_writer.string_value(value)?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_string_with_writer(
mut self,
f: impl FnOnce(StringValueWriter<'_>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
write_string_with_writer(&mut self.json_writer, f)?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_number<N: FiniteNumber>(mut self, value: N) -> Result<(), IoError> {
self.json_writer.number_value(value)?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_fp_number<N: FloatingPointNumber>(mut self, value: N) -> Result<(), JsonNumberError> {
self.json_writer.fp_number_value(value)?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_number_string(mut self, value: &str) -> Result<(), JsonNumberError> {
self.json_writer.number_value_from_string(value)?;
self.json_writer.finish_document()?;
Ok(())
}
#[cfg(feature = "serde")]
fn write_serialize<S: serde_core::ser::Serialize>(
mut self,
value: &S,
) -> Result<(), crate::serde::SerializerError> {
self.json_writer.serialize_value(value)?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_array(
mut self,
f: impl FnOnce(&mut ArrayWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
write_array(&mut self.json_writer, f)?;
self.json_writer.finish_document()?;
Ok(())
}
fn write_object(
mut self,
f: impl FnOnce(&mut ObjectWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
write_object(&mut self.json_writer, f)?;
self.json_writer.finish_document()?;
Ok(())
}
}
#[derive(Debug)]
pub struct ArrayWriter<'a, J: JsonWriter> {
json_writer: &'a mut ErrorSafeJsonWriter<J>,
}
impl<J: JsonWriter> ValueWriter<J> for &mut ArrayWriter<'_, J> {
fn write_null(self) -> Result<(), IoError> {
self.json_writer.null_value()
}
fn write_bool(self, value: bool) -> Result<(), IoError> {
self.json_writer.bool_value(value)
}
fn write_string(self, value: &str) -> Result<(), IoError> {
self.json_writer.string_value(value)
}
fn write_string_with_writer(
self,
f: impl FnOnce(StringValueWriter<'_>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
write_string_with_writer(self.json_writer, f)
}
fn write_number<N: FiniteNumber>(self, value: N) -> Result<(), IoError> {
self.json_writer.number_value(value)
}
fn write_fp_number<N: FloatingPointNumber>(self, value: N) -> Result<(), JsonNumberError> {
self.json_writer.fp_number_value(value)?;
Ok(())
}
fn write_number_string(self, value: &str) -> Result<(), JsonNumberError> {
self.json_writer.number_value_from_string(value)?;
Ok(())
}
#[cfg(feature = "serde")]
fn write_serialize<S: serde_core::ser::Serialize>(
self,
value: &S,
) -> Result<(), crate::serde::SerializerError> {
self.json_writer.serialize_value(value)?;
Ok(())
}
fn write_array(
self,
f: impl FnOnce(&mut ArrayWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
write_array(self.json_writer, f)
}
fn write_object(
self,
f: impl FnOnce(&mut ObjectWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
write_object(self.json_writer, f)
}
}
#[derive(Debug)]
pub struct ObjectWriter<'a, J: JsonWriter> {
json_writer: &'a mut ErrorSafeJsonWriter<J>,
}
impl<J: JsonWriter> ObjectWriter<'_, J> {
pub fn write_member(
&mut self,
name: &str,
f: impl FnOnce(MemberValueWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
self.json_writer.name(name)?;
let mut wrote_value = false;
let value_writer = MemberValueWriter {
json_writer: self.json_writer,
wrote_value: &mut wrote_value,
};
f(value_writer)?;
if !wrote_value {
self.json_writer.null_value()?;
}
Ok(())
}
pub fn write_null_member(&mut self, name: &str) -> Result<(), IoError> {
self.json_writer.name(name)?;
self.json_writer.null_value()
}
pub fn write_bool_member(&mut self, name: &str, value: bool) -> Result<(), IoError> {
self.json_writer.name(name)?;
self.json_writer.bool_value(value)
}
pub fn write_string_member(&mut self, name: &str, value: &str) -> Result<(), IoError> {
self.json_writer.name(name)?;
self.json_writer.string_value(value)
}
pub fn write_string_member_with_writer(
&mut self,
name: &str,
f: impl FnOnce(StringValueWriter<'_>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
self.json_writer.name(name)?;
write_string_with_writer(self.json_writer, f)
}
pub fn write_number_member<N: FiniteNumber>(
&mut self,
name: &str,
value: N,
) -> Result<(), IoError> {
self.json_writer.name(name)?;
self.json_writer.number_value(value)
}
pub fn write_fp_number_member<N: FloatingPointNumber>(
&mut self,
name: &str,
value: N,
) -> Result<(), JsonNumberError> {
self.json_writer.name(name)?;
self.json_writer.fp_number_value(value)
}
pub fn write_number_string_member(
&mut self,
name: &str,
value: &str,
) -> Result<(), JsonNumberError> {
self.json_writer.name(name)?;
self.json_writer.number_value_from_string(value)
}
#[cfg(feature = "serde")]
pub fn write_serialized_member<S: serde_core::ser::Serialize>(
&mut self,
name: &str,
value: &S,
) -> Result<(), crate::serde::SerializerError> {
self.json_writer.name(name)?;
self.json_writer.serialize_value(value)
}
pub fn write_array_member(
&mut self,
name: &str,
f: impl FnOnce(&mut ArrayWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
self.json_writer.name(name)?;
write_array(self.json_writer, f)
}
pub fn write_object_member(
&mut self,
name: &str,
f: impl FnOnce(&mut ObjectWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
self.json_writer.name(name)?;
write_object(self.json_writer, f)
}
}
pub struct MemberValueWriter<'a, J: JsonWriter> {
json_writer: &'a mut ErrorSafeJsonWriter<J>,
wrote_value: &'a mut bool,
}
impl<J: JsonWriter> ValueWriter<J> for MemberValueWriter<'_, J> {
fn write_null(self) -> Result<(), IoError> {
*self.wrote_value = true;
self.json_writer.null_value()
}
fn write_bool(self, value: bool) -> Result<(), IoError> {
*self.wrote_value = true;
self.json_writer.bool_value(value)
}
fn write_string(self, value: &str) -> Result<(), IoError> {
*self.wrote_value = true;
self.json_writer.string_value(value)
}
fn write_string_with_writer(
self,
f: impl FnOnce(StringValueWriter<'_>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
*self.wrote_value = true;
write_string_with_writer(self.json_writer, f)
}
fn write_number<N: FiniteNumber>(self, value: N) -> Result<(), IoError> {
*self.wrote_value = true;
self.json_writer.number_value(value)
}
fn write_fp_number<N: FloatingPointNumber>(self, value: N) -> Result<(), JsonNumberError> {
*self.wrote_value = true;
self.json_writer.fp_number_value(value)
}
fn write_number_string(self, value: &str) -> Result<(), JsonNumberError> {
*self.wrote_value = true;
self.json_writer.number_value_from_string(value)
}
#[cfg(feature = "serde")]
fn write_serialize<S: serde_core::ser::Serialize>(
self,
value: &S,
) -> Result<(), crate::serde::SerializerError> {
*self.wrote_value = true;
self.json_writer.serialize_value(value)
}
fn write_array(
self,
f: impl FnOnce(&mut ArrayWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
*self.wrote_value = true;
write_array(self.json_writer, f)
}
fn write_object(
self,
f: impl FnOnce(&mut ObjectWriter<'_, J>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
*self.wrote_value = true;
write_object(self.json_writer, f)
}
}
pub struct StringValueWriter<'a> {
delegate: &'a mut dyn AdvancedStringValueWriter,
}
impl Write for StringValueWriter<'_> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.delegate.write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.delegate.flush()
}
}
impl StringValueWriter<'_> {
pub fn write_str(&mut self, s: &str) -> Result<(), IoError> {
self.delegate.write_str(s)
}
}