use std::fmt::Display;
use std::fmt::Write as _;
use std::str::FromStr;
use serde::Serialize;
use serde::Serializer;
use serde_json::Map;
use serde_json::Number;
use serde_json::Value;
use super::JsonValueCompound;
use crate::decode::JsonDecoder;
use crate::encode::JsonIntegerSignedness;
use crate::encode::JsonSerializationError;
use crate::encode::JsonSerializationErrorKind;
use crate::encode::JsonSerializerStateError;
use crate::internal::SERDE_JSON_RAW_VALUE_TOKEN;
use crate::value::DuplicateKeyRejectingJsonValue;
const MAX_PREALLOCATED_ITEMS: usize = 1_024;
pub(in crate::value::json_value_encoder) const RAW_VALUE_TOKEN: &str = SERDE_JSON_RAW_VALUE_TOKEN;
#[inline(always)]
#[must_use]
fn preallocated_capacity(len: Option<usize>) -> usize {
len.unwrap_or(0).min(MAX_PREALLOCATED_ITEMS)
}
pub(in crate::value::json_value_encoder) fn decode_raw_value(text: &str) -> Result<Value, JsonSerializationError> {
let value = JsonDecoder::unlimited()
.decode_str::<DuplicateKeyRejectingJsonValue>(text)
.map_err(|_| JsonSerializationError::new(JsonSerializationErrorKind::InvalidRawValue))?;
Ok(value.into_inner())
}
#[derive(Debug, Clone, Copy)]
pub(in crate::value::json_value_encoder) struct JsonValueSerializer;
impl Serializer for JsonValueSerializer {
type Ok = Value;
type Error = JsonSerializationError;
type SerializeSeq = JsonValueCompound;
type SerializeTuple = JsonValueCompound;
type SerializeTupleStruct = JsonValueCompound;
type SerializeTupleVariant = JsonValueCompound;
type SerializeMap = JsonValueCompound;
type SerializeStruct = JsonValueCompound;
type SerializeStructVariant = JsonValueCompound;
#[inline(always)]
fn serialize_bool(self, value: bool) -> Result<Value, Self::Error> {
Ok(Value::Bool(value))
}
#[inline(always)]
fn serialize_i8(self, value: i8) -> Result<Value, Self::Error> {
self.serialize_i64(value.into())
}
#[inline(always)]
fn serialize_i16(self, value: i16) -> Result<Value, Self::Error> {
self.serialize_i64(value.into())
}
#[inline(always)]
fn serialize_i32(self, value: i32) -> Result<Value, Self::Error> {
self.serialize_i64(value.into())
}
#[inline(always)]
fn serialize_i64(self, value: i64) -> Result<Value, Self::Error> {
Ok(Value::Number(value.into()))
}
fn serialize_i128(self, value: i128) -> Result<Value, Self::Error> {
if let Ok(value) = i64::try_from(value) {
self.serialize_i64(value)
} else if let Ok(value) = u64::try_from(value) {
self.serialize_u64(value)
} else {
Err(JsonSerializationError::new(
JsonSerializationErrorKind::IntegerOutOfRange {
signedness: JsonIntegerSignedness::Signed,
},
))
}
}
#[inline(always)]
fn serialize_u8(self, value: u8) -> Result<Value, Self::Error> {
self.serialize_u64(value.into())
}
#[inline(always)]
fn serialize_u16(self, value: u16) -> Result<Value, Self::Error> {
self.serialize_u64(value.into())
}
#[inline(always)]
fn serialize_u32(self, value: u32) -> Result<Value, Self::Error> {
self.serialize_u64(value.into())
}
#[inline(always)]
fn serialize_u64(self, value: u64) -> Result<Value, Self::Error> {
Ok(Value::Number(value.into()))
}
fn serialize_u128(self, value: u128) -> Result<Value, Self::Error> {
u64::try_from(value)
.map_err(|_| {
JsonSerializationError::new(JsonSerializationErrorKind::IntegerOutOfRange {
signedness: JsonIntegerSignedness::Unsigned,
})
})
.and_then(|value| self.serialize_u64(value))
}
fn serialize_f32(self, value: f32) -> Result<Value, Self::Error> {
if !value.is_finite() {
return Err(JsonSerializationError::new(JsonSerializationErrorKind::NonFiniteFloat));
}
Number::from_str(&value.to_string())
.map(Value::Number)
.map_err(|_| JsonSerializationError::new(JsonSerializationErrorKind::InvalidNumberRepresentation))
}
fn serialize_f64(self, value: f64) -> Result<Value, Self::Error> {
Number::from_f64(value)
.map(Value::Number)
.ok_or_else(|| JsonSerializationError::new(JsonSerializationErrorKind::NonFiniteFloat))
}
#[inline]
fn serialize_char(self, value: char) -> Result<Value, Self::Error> {
Ok(Value::String(value.to_string()))
}
#[inline]
fn serialize_str(self, value: &str) -> Result<Value, Self::Error> {
Ok(Value::String(value.to_owned()))
}
fn serialize_bytes(self, value: &[u8]) -> Result<Value, Self::Error> {
Ok(Value::Array(
value.iter().map(|value| Value::Number((*value).into())).collect(),
))
}
#[inline(always)]
fn serialize_none(self) -> Result<Value, Self::Error> {
self.serialize_unit()
}
#[inline(always)]
fn serialize_some<T>(self, value: &T) -> Result<Value, Self::Error>
where
T: Serialize + ?Sized,
{
value.serialize(self)
}
#[inline(always)]
fn serialize_unit(self) -> Result<Value, Self::Error> {
Ok(Value::Null)
}
#[inline(always)]
fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Self::Error> {
self.serialize_unit()
}
#[inline(always)]
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Value, Self::Error> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Value, Self::Error>
where
T: Serialize + ?Sized,
{
let value = value.serialize(self)?;
if name != RAW_VALUE_TOKEN {
return Ok(value);
}
let Value::String(text) = value else {
return Err(JsonSerializationError::new(
JsonSerializationErrorKind::InvalidSerializerState {
reason: JsonSerializerStateError::InvalidRawValueProtocol,
},
));
};
decode_raw_value(&text)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Value, Self::Error>
where
T: Serialize + ?Sized,
{
let mut object = Map::new();
object.insert(variant.to_owned(), value.serialize(self)?);
Ok(Value::Object(object))
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Ok(JsonValueCompound::sequence(preallocated_capacity(len)))
}
#[inline(always)]
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.serialize_seq(Some(len))
}
#[inline(always)]
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Ok(JsonValueCompound::tuple_variant(
variant,
preallocated_capacity(Some(len)),
))
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Ok(JsonValueCompound::map(preallocated_capacity(len)))
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, Self::Error> {
if name == RAW_VALUE_TOKEN {
Ok(JsonValueCompound::raw_value())
} else {
Ok(JsonValueCompound::map(preallocated_capacity(Some(len))))
}
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Ok(JsonValueCompound::struct_variant(
variant,
preallocated_capacity(Some(len)),
))
}
fn collect_str<T>(self, value: &T) -> Result<Value, Self::Error>
where
T: Display + ?Sized,
{
let mut text = String::new();
write!(&mut text, "{value}")
.map_err(|_| JsonSerializationError::new(JsonSerializationErrorKind::DisplayFormattingFailed))?;
self.serialize_str(&text)
}
}