use std::fmt::Display;
use crate::writer::{FiniteNumber, FloatingPointNumber, JsonNumberError, JsonWriter};
use serde_core::ser::{Impossible, Serialize, Serializer};
use thiserror::Error;
type IoError = std::io::Error;
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum SerializerError {
#[error("{0}")]
Custom(String),
#[error("IO error: {0}")]
IoError(#[from] IoError),
#[error("invalid number: {0}")]
InvalidNumber(String),
#[error("incorrect elements count, expected {expected} but got {actual}")]
IncorrectElementsCount {
expected: usize,
actual: usize,
},
#[error("map key cannot be converted to string")]
MapKeyNotString,
}
impl serde_core::ser::Error for SerializerError {
fn custom<T: Display>(msg: T) -> Self {
SerializerError::Custom(msg.to_string())
}
}
#[derive(Debug)]
pub struct JsonWriterSerializer<'a, W> {
json_writer: &'a mut W,
}
impl<'a, W: JsonWriter> JsonWriterSerializer<'a, W> {
pub fn new(json_writer: &'a mut W) -> Self {
JsonWriterSerializer { json_writer }
}
}
fn map_number_err(e: JsonNumberError) -> SerializerError {
match e {
JsonNumberError::InvalidNumber(e) => SerializerError::InvalidNumber(e),
JsonNumberError::IoError(e) => SerializerError::IoError(e),
}
}
impl<'s, 'a, W: JsonWriter> Serializer for &'s mut JsonWriterSerializer<'a, W> {
type Ok = ();
type Error = SerializerError;
type SerializeSeq = SerializeSeq<'s, 'a, W>;
type SerializeTuple = SerializeTuple<'s, 'a, W>;
type SerializeTupleStruct = SerializeTupleStruct<'s, 'a, W>;
type SerializeTupleVariant = SerializeTupleVariant<'s, 'a, W>;
type SerializeMap = SerializeMap<'s, 'a, W>;
type SerializeStruct = SerializeStruct<'s, 'a, W>;
type SerializeStructVariant = SerializeStructVariant<'s, 'a, W>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
self.json_writer.bool_value(v)?;
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
self.json_writer.number_value(v)?;
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.json_writer
.fp_number_value(v)
.map_err(map_number_err)?;
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
self.json_writer
.fp_number_value(v)
.map_err(map_number_err)?;
Ok(())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
self.json_writer.string_value(&v.to_string())?;
Ok(())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
self.json_writer.string_value(v)?;
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
self.json_writer.begin_array()?;
for b in v {
self.json_writer.number_value(*b)?;
}
self.json_writer.end_array()?;
Ok(())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
self.json_writer.null_value()?;
Ok(())
}
fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> {
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
self.json_writer.null_value()?;
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
self.json_writer.null_value()?;
Ok(())
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
self.json_writer.string_value(variant)?;
Ok(())
}
fn serialize_newtype_struct<T: Serialize + ?Sized>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
value.serialize(self)
}
fn serialize_newtype_variant<T: Serialize + ?Sized>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
self.json_writer.begin_object()?;
self.json_writer.name(variant)?;
value.serialize(&mut *self)?;
self.json_writer.end_object()?;
Ok(())
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
self.json_writer.begin_array()?;
Ok(SerializeSeq {
ser: self,
expected_len: len,
len: 0,
})
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.json_writer.begin_array()?;
Ok(SerializeTuple {
ser: self,
expected_len: len,
len: 0,
})
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.json_writer.begin_array()?;
Ok(SerializeTupleStruct {
ser: self,
expected_len: len,
len: 0,
})
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
self.json_writer.begin_object()?;
self.json_writer.name(variant)?;
self.json_writer.begin_array()?;
Ok(SerializeTupleVariant {
ser: self,
expected_len: len,
len: 0,
})
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
self.json_writer.begin_object()?;
Ok(SerializeMap {
ser: self,
expected_len: len,
len: 0,
expects_entry_value: false,
})
}
fn serialize_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
self.json_writer.begin_object()?;
Ok(SerializeStruct {
ser: self,
expected_len: len,
len: 0,
})
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
self.json_writer.begin_object()?;
self.json_writer.name(variant)?;
self.json_writer.begin_object()?;
Ok(SerializeStructVariant {
ser: self,
expected_len: len,
len: 0,
})
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct SerializeSeq<'s, 'a, W: JsonWriter> {
ser: &'s mut JsonWriterSerializer<'a, W>,
expected_len: Option<usize>,
len: usize,
}
impl<W: JsonWriter> serde_core::ser::SerializeSeq for SerializeSeq<'_, '_, W> {
type Ok = ();
type Error = SerializerError;
fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> {
if let Some(expected_len) = self.expected_len {
if self.len >= expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: expected_len,
actual: self.len + 1,
});
}
self.len += 1;
}
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
if let Some(expected_len) = self.expected_len {
if self.len < expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: expected_len,
actual: self.len,
});
}
}
self.ser.json_writer.end_array()?;
Ok(())
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct SerializeTuple<'s, 'a, W: JsonWriter> {
ser: &'s mut JsonWriterSerializer<'a, W>,
expected_len: usize,
len: usize,
}
impl<W: JsonWriter> serde_core::ser::SerializeTuple for SerializeTuple<'_, '_, W> {
type Ok = ();
type Error = SerializerError;
fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> {
if self.len >= self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len + 1,
});
}
self.len += 1;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.len < self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len,
});
}
self.ser.json_writer.end_array()?;
Ok(())
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct SerializeTupleStruct<'s, 'a, W: JsonWriter> {
ser: &'s mut JsonWriterSerializer<'a, W>,
expected_len: usize,
len: usize,
}
impl<W: JsonWriter> serde_core::ser::SerializeTupleStruct for SerializeTupleStruct<'_, '_, W> {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> {
if self.len >= self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len + 1,
});
}
self.len += 1;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.len < self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len,
});
}
self.ser.json_writer.end_array()?;
Ok(())
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct SerializeTupleVariant<'s, 'a, W: JsonWriter> {
ser: &'s mut JsonWriterSerializer<'a, W>,
expected_len: usize,
len: usize,
}
impl<W: JsonWriter> serde_core::ser::SerializeTupleVariant for SerializeTupleVariant<'_, '_, W> {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> {
if self.len >= self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len + 1,
});
}
self.len += 1;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.len < self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len,
});
}
self.ser.json_writer.end_array()?;
self.ser.json_writer.end_object()?;
Ok(())
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct SerializeMap<'s, 'a, W: JsonWriter> {
ser: &'s mut JsonWriterSerializer<'a, W>,
expected_len: Option<usize>,
len: usize,
expects_entry_value: bool,
}
impl<W: JsonWriter> serde_core::ser::SerializeMap for SerializeMap<'_, '_, W> {
type Ok = ();
type Error = SerializerError;
fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<(), Self::Error> {
if self.expects_entry_value {
panic!("Incorrect usage: Cannot serialize key when value is expected")
}
if let Some(expected_len) = self.expected_len {
if self.len >= expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: expected_len,
actual: self.len + 1,
});
}
self.len += 1;
}
self.expects_entry_value = true;
key.serialize(&mut MapKeyStringSerializer {
json_writer: self.ser.json_writer,
})
}
fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> {
if !self.expects_entry_value {
panic!("Incorrect usage: Cannot serialize value when key is expected")
}
self.expects_entry_value = false;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.expects_entry_value {
panic!("Incorrect usage: Cannot end map when value is expected")
}
if let Some(expected_len) = self.expected_len {
if self.len < expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: expected_len,
actual: self.len,
});
}
}
self.ser.json_writer.end_object()?;
Ok(())
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct SerializeStruct<'s, 'a, W: JsonWriter> {
ser: &'s mut JsonWriterSerializer<'a, W>,
expected_len: usize,
len: usize,
}
impl<W: JsonWriter> serde_core::ser::SerializeStruct for SerializeStruct<'_, '_, W> {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T: Serialize + ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error> {
if self.len >= self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len + 1,
});
}
self.len += 1;
self.ser.json_writer.name(key)?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.len < self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len,
});
}
self.ser.json_writer.end_object()?;
Ok(())
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct SerializeStructVariant<'s, 'a, W: JsonWriter> {
ser: &'s mut JsonWriterSerializer<'a, W>,
expected_len: usize,
len: usize,
}
impl<W: JsonWriter> serde_core::ser::SerializeStructVariant for SerializeStructVariant<'_, '_, W> {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T: Serialize + ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error> {
if self.len >= self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len + 1,
});
}
self.len += 1;
self.ser.json_writer.name(key)?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
if self.len < self.expected_len {
return Err(SerializerError::IncorrectElementsCount {
expected: self.expected_len,
actual: self.len,
});
}
self.ser.json_writer.end_object()?;
self.ser.json_writer.end_object()?;
Ok(())
}
}
#[derive(Debug)]
struct MapKeyStringSerializer<'a, W: JsonWriter> {
json_writer: &'a mut W,
}
impl<W: JsonWriter> MapKeyStringSerializer<'_, W> {
fn serialize_finite_number_key<N: FiniteNumber>(
&mut self,
number: N,
) -> Result<(), SerializerError> {
number
.use_json_number(|s| self.json_writer.name(s))
.map_err(SerializerError::IoError)
}
fn serialize_fp_number_key<N: FloatingPointNumber>(
&mut self,
number: N,
) -> Result<(), SerializerError> {
number
.use_json_number(|s| self.json_writer.name(s))
.map_err(map_number_err)
}
}
fn err_key_not_string<T>() -> Result<T, SerializerError> {
Err(SerializerError::MapKeyNotString)
}
impl<W: JsonWriter> Serializer for &mut MapKeyStringSerializer<'_, W> {
type Ok = ();
type Error = SerializerError;
type SerializeSeq = Impossible<(), Self::Error>;
type SerializeTuple = Impossible<(), Self::Error>;
type SerializeTupleStruct = Impossible<(), Self::Error>;
type SerializeTupleVariant = Impossible<(), Self::Error>;
type SerializeMap = Impossible<(), Self::Error>;
type SerializeStruct = Impossible<(), Self::Error>;
type SerializeStructVariant = Impossible<(), Self::Error>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
self.serialize_str(if v { "true" } else { "false" })
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
self.serialize_finite_number_key(v)
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.serialize_fp_number_key(v)
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
self.serialize_fp_number_key(v)
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
self.serialize_str(&v.to_string())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
self.json_writer.name(v)?;
Ok(())
}
fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> {
value.serialize(self)
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T: Serialize + ?Sized>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
value.serialize(self)
}
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
err_key_not_string()
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
err_key_not_string()
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
err_key_not_string()
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
err_key_not_string()
}
fn serialize_newtype_variant<T: Serialize + ?Sized>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<Self::Ok, Self::Error> {
err_key_not_string()
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
err_key_not_string()
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
err_key_not_string()
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
err_key_not_string()
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
err_key_not_string()
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
err_key_not_string()
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
err_key_not_string()
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
err_key_not_string()
}
}
#[cfg(test)]
mod tests {
use std::vec;
use serde_core::{
Serialize, Serializer,
ser::{
SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant,
},
};
use super::{JsonWriterSerializer, SerializerError};
use crate::writer::{JsonStreamWriter, JsonWriter};
fn assert_serialized<
F: FnOnce(
&mut JsonWriterSerializer<'_, JsonStreamWriter<&mut Vec<u8>>>,
) -> Result<(), SerializerError>,
>(
serializing_function: F,
expected_json: &str,
) {
let mut writer = Vec::<u8>::new();
let mut json_writer = JsonStreamWriter::new(&mut writer);
let mut serializer = JsonWriterSerializer::new(&mut json_writer);
serializing_function(&mut serializer).unwrap();
json_writer.finish_document().unwrap();
assert_eq!(
expected_json,
String::from_utf8(writer).unwrap(),
"expected JSON does not match Struson output"
);
}
fn assert_serialized_serde_json<
F: FnOnce(&mut serde_json::Serializer<&mut Vec<u8>>) -> Result<(), serde_json::Error>,
>(
serializing_function: F,
expected_json: &str,
) {
let mut writer = Vec::<u8>::new();
let mut serializer = serde_json::Serializer::new(&mut writer);
serializing_function(&mut serializer).unwrap();
assert_eq!(
expected_json,
String::from_utf8(writer).unwrap(),
"expected JSON does not match serde_json output"
);
}
macro_rules! assert_serialized_cmp {
(|$serializer:ident| $serializing_function_body:block, $expected_json:expr) => {
assert_serialized(|$serializer| $serializing_function_body, $expected_json);
{
struct S;
impl Serialize for S {
fn serialize<S: Serializer>(&self, $serializer: S) -> Result<S::Ok, S::Error> {
$serializing_function_body
}
}
let mut writer = Vec::<u8>::new();
let mut serializer = serde_json::Serializer::new(&mut writer);
S.serialize(&mut serializer).unwrap();
assert_eq!(
$expected_json,
String::from_utf8(writer).unwrap(),
"expected JSON does not match serde_json output"
);
}
};
($serializing_function:expr, $expected_json:expr) => {
assert_serialized($serializing_function, $expected_json);
assert_serialized_serde_json($serializing_function, $expected_json);
}
}
fn assert_number_error<
F: FnOnce(
&mut JsonWriterSerializer<'_, JsonStreamWriter<std::io::Sink>>,
) -> Result<(), SerializerError>,
>(
serializing_function: F,
expected_error_message: &str,
) {
let mut json_writer = JsonStreamWriter::new(std::io::sink());
let mut serializer = JsonWriterSerializer::new(&mut json_writer);
match serializing_function(&mut serializer) {
Ok(_) => panic!("Should have failed with error message: {expected_error_message}"),
Err(e) => match e {
SerializerError::InvalidNumber(message) => {
assert_eq!(expected_error_message, message)
}
_ => panic!("Unexpected error: {e:?}"),
},
}
}
fn assert_elements_count_error<
F1: FnOnce(
&mut JsonWriterSerializer<'_, JsonStreamWriter<std::io::Sink>>,
) -> Result<(), SerializerError>,
F2: FnOnce(
&mut JsonWriterSerializer<'_, JsonStreamWriter<std::io::Sink>>,
) -> Result<(), SerializerError>,
>(
serialize_none: F1,
serialize_one: F2,
) {
fn assert_result<
F: FnOnce(
&mut JsonWriterSerializer<'_, JsonStreamWriter<std::io::Sink>>,
) -> Result<(), SerializerError>,
>(
serializing_function: F,
expected_expected: usize,
expected_actual: usize,
) {
let mut json_writer = JsonStreamWriter::new(std::io::sink());
let mut serializer = JsonWriterSerializer::new(&mut json_writer);
match serializing_function(&mut serializer) {
Ok(_) => panic!("Should have failed with error"),
Err(e) => match e {
SerializerError::IncorrectElementsCount { expected, actual } => {
assert_eq!(expected_expected, expected);
assert_eq!(expected_actual, actual);
}
_ => panic!("Unexpected error: {e:?}"),
},
}
}
assert_result(serialize_none, 1, 0);
assert_result(serialize_one, 0, 1);
}
#[test]
fn serialize_bool() {
assert_serialized_cmp!(|s| s.serialize_bool(true), "true");
assert_serialized_cmp!(|s| s.serialize_bool(false), "false");
}
#[test]
fn serialize_bytes() {
assert_serialized_cmp!(|s| s.serialize_bytes(&[]), "[]");
assert_serialized_cmp!(|s| s.serialize_bytes(&[0, 127, 255]), "[0,127,255]");
}
#[test]
fn serialize_char() {
assert_serialized_cmp!(|s| s.serialize_char('a'), "\"a\"");
assert_serialized_cmp!(|s| s.serialize_char('\0'), "\"\\u0000\"");
assert_serialized_cmp!(|s| s.serialize_char('\u{10FFFF}'), "\"\u{10FFFF}\"");
}
#[test]
fn serialize_f32() {
assert_serialized(|s| s.serialize_f32(0.0), "0");
assert_serialized(|s| s.serialize_f32(-0.0), "-0");
assert_serialized_cmp!(|s| s.serialize_f32(123.45), "123.45");
assert_number_error(
|s| s.serialize_f32(f32::NAN),
&format!("non-finite number: {}", f32::NAN),
);
assert_number_error(
|s| s.serialize_f32(f32::INFINITY),
&format!("non-finite number: {}", f32::INFINITY),
);
}
#[test]
fn serialize_f64() {
assert_serialized(|s| s.serialize_f64(0.0), "0");
assert_serialized(|s| s.serialize_f64(-0.0), "-0");
assert_serialized_cmp!(|s| s.serialize_f64(123.45), "123.45");
assert_number_error(
|s| s.serialize_f64(f64::NAN),
&format!("non-finite number: {}", f64::NAN),
);
assert_number_error(
|s| s.serialize_f64(f64::INFINITY),
&format!("non-finite number: {}", f64::INFINITY),
);
}
#[test]
fn serialize_i8() {
assert_serialized_cmp!(|s| s.serialize_i8(-3), "-3");
assert_serialized_cmp!(|s| s.serialize_i8(3), "3");
assert_serialized_cmp!(|s| s.serialize_i8(i8::MIN), "-128");
assert_serialized_cmp!(|s| s.serialize_i8(i8::MAX), "127");
}
#[test]
fn serialize_i16() {
assert_serialized_cmp!(|s| s.serialize_i16(-3), "-3");
assert_serialized_cmp!(|s| s.serialize_i16(3), "3");
assert_serialized_cmp!(|s| s.serialize_i16(i16::MIN), "-32768");
assert_serialized_cmp!(|s| s.serialize_i16(i16::MAX), "32767");
}
#[test]
fn serialize_i32() {
assert_serialized_cmp!(|s| s.serialize_i32(-3), "-3");
assert_serialized_cmp!(|s| s.serialize_i32(3), "3");
assert_serialized_cmp!(|s| s.serialize_i32(i32::MIN), "-2147483648");
assert_serialized_cmp!(|s| s.serialize_i32(i32::MAX), "2147483647");
}
#[test]
fn serialize_i64() {
assert_serialized_cmp!(|s| s.serialize_i64(-3), "-3");
assert_serialized_cmp!(|s| s.serialize_i64(3), "3");
assert_serialized_cmp!(|s| s.serialize_i64(i64::MIN), "-9223372036854775808");
assert_serialized_cmp!(|s| s.serialize_i64(i64::MAX), "9223372036854775807");
}
#[test]
fn serialize_i128() {
assert_serialized_cmp!(|s| s.serialize_i128(-3), "-3");
assert_serialized_cmp!(|s| s.serialize_i128(3), "3");
assert_serialized_cmp!(
|s| s.serialize_i128(i128::MIN),
"-170141183460469231731687303715884105728"
);
assert_serialized_cmp!(
|s| s.serialize_i128(i128::MAX),
"170141183460469231731687303715884105727"
);
}
#[test]
fn serialize_u8() {
assert_serialized_cmp!(|s| s.serialize_u8(3), "3");
assert_serialized_cmp!(|s| s.serialize_u8(u8::MAX), "255");
}
#[test]
fn serialize_u16() {
assert_serialized_cmp!(|s| s.serialize_u16(3), "3");
assert_serialized_cmp!(|s| s.serialize_u16(u16::MAX), "65535");
}
#[test]
fn serialize_u32() {
assert_serialized_cmp!(|s| s.serialize_u32(3), "3");
assert_serialized_cmp!(|s| s.serialize_u32(u32::MAX), "4294967295");
}
#[test]
fn serialize_u64() {
assert_serialized_cmp!(|s| s.serialize_u64(3), "3");
assert_serialized_cmp!(|s| s.serialize_u64(u64::MAX), "18446744073709551615");
}
#[test]
fn serialize_u128() {
assert_serialized_cmp!(|s| s.serialize_u128(3), "3");
assert_serialized_cmp!(
|s| s.serialize_u128(u128::MAX),
"340282366920938463463374607431768211455"
);
}
mod serialize_map {
use super::*;
#[test]
fn serialize() {
assert_serialized_cmp!(
|s| {
let map = s.serialize_map(None)?;
map.end()
},
"{}"
);
assert_serialized_cmp!(
|s| {
let mut map = s.serialize_map(None)?;
map.serialize_key("a")?;
map.serialize_value(&1)?;
map.end()
},
r#"{"a":1}"#
);
assert_serialized_cmp!(
|s| {
let mut map = s.serialize_map(Some(1))?;
map.serialize_key("a")?;
map.serialize_value(&1)?;
map.end()
},
r#"{"a":1}"#
);
assert_serialized_cmp!(
|s| {
let mut map = s.serialize_map(None)?;
map.serialize_key("a")?;
map.serialize_value(&1)?;
map.serialize_key("a")?;
map.serialize_value(&2)?;
map.end()
},
r#"{"a":1,"a":2}"#
);
assert_serialized_cmp!(
|s| {
let mut map = s.serialize_map(None)?;
map.serialize_key("a")?;
struct NestedMap;
impl Serialize for NestedMap {
fn serialize<S: Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
let mut map = serializer.serialize_map(None)?;
map.serialize_key("b")?;
map.serialize_value(&1)?;
map.end()
}
}
map.serialize_value(&NestedMap)?;
map.end()
},
r#"{"a":{"b":1}}"#
);
assert_elements_count_error(
|s| {
let map = s.serialize_map(Some(1))?;
map.end()
},
|s| {
let mut map = s.serialize_map(Some(0))?;
map.serialize_key("a")
},
);
}
#[test]
fn string_key_conversion() {
assert_serialized_cmp!(
|s| {
let mut map = s.serialize_map(None)?;
map.serialize_key(&true)?;
map.serialize_value(&0)?;
map.serialize_key(&false)?;
map.serialize_value(&0)?;
map.serialize_key(&2_u8)?;
map.serialize_value(&0)?;
map.serialize_key(&3_i128)?;
map.serialize_value(&0)?;
map.serialize_key(&1.23_f32)?;
map.serialize_value(&0)?;
map.serialize_key(&'a')?;
map.serialize_value(&0)?;
map.serialize_key(&Some("value"))?;
map.serialize_value(&0)?;
struct UnitVariant;
impl Serialize for UnitVariant {
fn serialize<S: Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_unit_variant("name", 1, "UnitVariant")
}
}
map.serialize_key(&UnitVariant)?;
map.serialize_value(&0)?;
struct NewtypeStruct;
impl Serialize for NewtypeStruct {
fn serialize<S: Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_newtype_struct("name", "NewtypeStruct")
}
}
map.serialize_key(&NewtypeStruct)?;
map.serialize_value(&0)?;
map.end()
},
r#"{"true":0,"false":0,"2":0,"3":0,"1.23":0,"a":0,"value":0,"UnitVariant":0,"NewtypeStruct":0}"#
);
}
#[test]
fn string_key_error() {
macro_rules! assert_map_key_error {
($key:expr, $err_pattern:pat_param => $err_assertion:expr) => {
{
let mut json_writer = JsonStreamWriter::new(std::io::sink());
let mut serializer = JsonWriterSerializer::new(&mut json_writer);
let mut map = serializer.serialize_map(None).unwrap();
match map.serialize_key(&$key) {
Ok(_) => panic!("Should have failed for Struson"),
Err(e) => match e {
$err_pattern => $err_assertion,
_ => panic!("Unexpected error for Struson: {e:?}"),
},
}
}
{
let mut serializer = serde_json::Serializer::new(std::io::sink());
let mut map = serializer.serialize_map(None).unwrap();
match map.serialize_key(&$key) {
Ok(_) => panic!("Should have failed for serde_json"),
Err(_) => {},
}
}
};
($key:expr, $err_pattern:pat_param) => {
assert_map_key_error!($key, $err_pattern => {});
};
}
assert_map_key_error!(
f32::NAN,
SerializerError::InvalidNumber(message) => assert_eq!(format!("non-finite number: {}", f32::NAN), message)
);
assert_map_key_error!(
f64::INFINITY,
SerializerError::InvalidNumber(message) => assert_eq!(format!("non-finite number: {}", f64::INFINITY), message)
);
assert_map_key_error!([1_u8], SerializerError::MapKeyNotString);
assert_map_key_error!(vec!["a"], SerializerError::MapKeyNotString);
struct NewtypeStruct<N: Serialize>(N);
impl<N: Serialize> Serialize for NewtypeStruct<N> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_newtype_struct("name", &self.0)
}
}
assert_map_key_error!(NewtypeStruct(vec!["a"]), SerializerError::MapKeyNotString);
}
fn use_map_serializer<
F: FnOnce(
crate::serde::ser::SerializeMap<'_, '_, JsonStreamWriter<std::io::Sink>>,
) -> Result<(), SerializerError>,
>(
serializing_function: F,
) {
let mut json_writer = JsonStreamWriter::new(std::io::sink());
let mut serializer = JsonWriterSerializer::new(&mut json_writer);
let map = serializer.serialize_map(None).unwrap();
serializing_function(map).unwrap();
}
#[test]
#[should_panic(expected = "Incorrect usage: Cannot serialize value when key is expected")]
fn unexpected_value() {
use_map_serializer(|mut map| map.serialize_value(&1));
}
#[test]
#[should_panic(expected = "Incorrect usage: Cannot serialize key when value is expected")]
fn unexpected_key() {
use_map_serializer(|mut map| {
map.serialize_key("a")?;
map.serialize_key("b")
});
}
#[test]
#[should_panic(expected = "Incorrect usage: Cannot end map when value is expected")]
fn end_missing_value() {
use_map_serializer(|mut map| {
map.serialize_key("a")?;
map.end()
});
}
}
#[test]
fn serialize_newtype_struct() {
assert_serialized_cmp!(
|s| s.serialize_newtype_struct("name", &"value"),
"\"value\""
);
}
#[test]
fn serialize_newtype_variant() {
assert_serialized_cmp!(
|s| s.serialize_newtype_variant("name", 1, "variant", &"value"),
r#"{"variant":"value"}"#
);
}
#[test]
fn serialize_none() {
assert_serialized_cmp!(|s| s.serialize_none(), "null");
}
#[test]
fn serialize_some() {
assert_serialized_cmp!(|s| s.serialize_some("value"), "\"value\"");
}
#[test]
fn serialize_seq() {
assert_serialized_cmp!(
|s| {
let seq = s.serialize_seq(None)?;
seq.end()
},
"[]"
);
assert_serialized_cmp!(
|s| {
let mut seq = s.serialize_seq(None)?;
seq.serialize_element(&1)?;
seq.end()
},
"[1]"
);
assert_serialized_cmp!(
|s| {
let mut seq = s.serialize_seq(Some(1))?;
seq.serialize_element(&1)?;
seq.end()
},
"[1]"
);
assert_serialized_cmp!(
|s| {
let mut seq = s.serialize_seq(None)?;
seq.serialize_element(&1)?;
seq.serialize_element(&2)?;
seq.end()
},
"[1,2]"
);
assert_serialized_cmp!(
|s| {
let mut seq = s.serialize_seq(None)?;
struct NestedSeq;
impl Serialize for NestedSeq {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element(&1)?;
seq.serialize_element(&2)?;
seq.end()
}
}
seq.serialize_element(&NestedSeq)?;
seq.end()
},
"[[1,2]]"
);
assert_elements_count_error(
|s| {
let seq = s.serialize_seq(Some(1))?;
seq.end()
},
|s| {
let mut seq = s.serialize_seq(Some(0))?;
seq.serialize_element(&1)
},
);
}
#[test]
fn serialize_str() {
assert_serialized_cmp!(|s| s.serialize_str(""), "\"\"");
assert_serialized_cmp!(|s| s.serialize_str("test"), "\"test\"");
assert_serialized_cmp!(|s| s.serialize_str("\0"), "\"\\u0000\"");
assert_serialized_cmp!(|s| s.serialize_str("\u{10FFFF}"), "\"\u{10FFFF}\"");
}
#[test]
fn serialize_struct() {
assert_serialized_cmp!(
|s| {
let struc = s.serialize_struct("name", 0)?;
struc.end()
},
"{}"
);
assert_serialized_cmp!(
|s| {
let mut struc = s.serialize_struct("name", 1)?;
struc.serialize_field("key", &1)?;
struc.end()
},
r#"{"key":1}"#
);
assert_serialized_cmp!(
|s| {
let mut struc = s.serialize_struct("name", 2)?;
struc.serialize_field("key1", &1)?;
struc.skip_field("skipped")?;
struc.serialize_field("key2", &2)?;
struc.end()
},
r#"{"key1":1,"key2":2}"#
);
assert_elements_count_error(
|s| {
let struc = s.serialize_struct("name", 1)?;
struc.end()
},
|s| {
let mut struc = s.serialize_struct("name", 0)?;
struc.serialize_field("key1", &1)
},
);
}
#[test]
fn serialize_struct_variant() {
assert_serialized_cmp!(
|s| {
let struc = s.serialize_struct_variant("name", 1, "variant", 0)?;
struc.end()
},
r#"{"variant":{}}"#
);
assert_serialized_cmp!(
|s| {
let mut struc = s.serialize_struct_variant("name", 1, "variant", 1)?;
struc.serialize_field("key", &1)?;
struc.end()
},
r#"{"variant":{"key":1}}"#
);
assert_serialized_cmp!(
|s| {
let mut struc = s.serialize_struct_variant("name", 1, "variant", 2)?;
struc.serialize_field("key1", &1)?;
struc.skip_field("skipped")?;
struc.serialize_field("key2", &2)?;
struc.end()
},
r#"{"variant":{"key1":1,"key2":2}}"#
);
assert_elements_count_error(
|s| {
let struc = s.serialize_struct_variant("name", 1, "variant", 1)?;
struc.end()
},
|s| {
let mut struc = s.serialize_struct_variant("name", 1, "variant", 0)?;
struc.serialize_field("key1", &1)
},
);
}
#[test]
fn serialize_tuple() {
assert_serialized_cmp!(
|s| {
let tuple = s.serialize_tuple(0)?;
tuple.end()
},
"[]"
);
assert_serialized_cmp!(
|s| {
let mut tuple = s.serialize_tuple(1)?;
tuple.serialize_element(&1)?;
tuple.end()
},
"[1]"
);
assert_serialized_cmp!(
|s| {
let mut tuple = s.serialize_tuple(2)?;
tuple.serialize_element(&1)?;
tuple.serialize_element(&2)?;
tuple.end()
},
"[1,2]"
);
assert_elements_count_error(
|s| {
let tuple = s.serialize_tuple(1)?;
tuple.end()
},
|s| {
let mut tuple = s.serialize_tuple(0)?;
tuple.serialize_element(&1)
},
);
}
#[test]
fn serialize_tuple_struct() {
assert_serialized_cmp!(
|s| {
let tuple = s.serialize_tuple_struct("name", 0)?;
tuple.end()
},
"[]"
);
assert_serialized_cmp!(
|s| {
let mut tuple = s.serialize_tuple_struct("name", 1)?;
tuple.serialize_field(&1)?;
tuple.end()
},
"[1]"
);
assert_serialized_cmp!(
|s| {
let mut tuple = s.serialize_tuple_struct("name", 2)?;
tuple.serialize_field(&1)?;
tuple.serialize_field(&2)?;
tuple.end()
},
"[1,2]"
);
assert_elements_count_error(
|s| {
let tuple = s.serialize_tuple(1)?;
tuple.end()
},
|s| {
let mut tuple = s.serialize_tuple(0)?;
tuple.serialize_element(&1)
},
);
}
#[test]
fn serialize_tuple_variant() {
assert_serialized_cmp!(
|s| {
let tuple = s.serialize_tuple_variant("name", 0, "variant", 0)?;
tuple.end()
},
r#"{"variant":[]}"#
);
assert_serialized_cmp!(
|s| {
let mut tuple = s.serialize_tuple_variant("name", 0, "variant", 1)?;
tuple.serialize_field(&1)?;
tuple.end()
},
r#"{"variant":[1]}"#
);
assert_serialized_cmp!(
|s| {
let mut tuple = s.serialize_tuple_variant("name", 0, "variant", 2)?;
tuple.serialize_field(&1)?;
tuple.serialize_field(&2)?;
tuple.end()
},
r#"{"variant":[1,2]}"#
);
assert_elements_count_error(
|s| {
let tuple = s.serialize_tuple_variant("name", 0, "variant", 1)?;
tuple.end()
},
|s| {
let mut tuple = s.serialize_tuple_variant("name", 0, "variant", 0)?;
tuple.serialize_field(&1)
},
);
}
#[test]
fn serialize_unit() {
assert_serialized_cmp!(|s| s.serialize_unit(), "null");
}
#[test]
fn serialize_unit_struct() {
assert_serialized_cmp!(|s| s.serialize_unit_struct("name"), "null");
}
#[test]
fn serialize_unit_variant() {
assert_serialized_cmp!(
|s| s.serialize_unit_variant("name", 0, "variant"),
"\"variant\""
);
}
}