use serde::Serialize;
use serde::ser::SerializeMap;
use serde::ser::SerializeSeq;
use serde::ser::SerializeStruct;
use serde::ser::SerializeStructVariant;
use serde::ser::SerializeTuple;
use serde::ser::SerializeTupleStruct;
use serde::ser::SerializeTupleVariant;
use serde_json::Map;
use serde_json::Value;
use super::JsonValueMapKeySerializer;
use super::JsonValueSerializer;
use super::json_value_serializer::RAW_VALUE_TOKEN;
use super::json_value_serializer::decode_raw_value;
use crate::encode::JsonSerializationError;
use crate::encode::JsonSerializationErrorKind;
use crate::encode::JsonSerializerStateError;
pub(in crate::value::json_value_encoder) enum JsonValueCompound {
Sequence(
Vec<Value>,
),
Map {
values: Map<String, Value>,
next_key: Option<String>,
},
TupleVariant {
variant: String,
values: Vec<Value>,
},
StructVariant {
variant: String,
values: Map<String, Value>,
},
RawValue {
text: Option<String>,
},
}
impl JsonValueCompound {
#[inline]
#[must_use]
pub(in crate::value::json_value_encoder) fn sequence(capacity: usize) -> Self {
Self::Sequence(Vec::with_capacity(capacity))
}
#[inline]
#[must_use]
pub(in crate::value::json_value_encoder) fn map(capacity: usize) -> Self {
Self::Map {
values: Map::with_capacity(capacity),
next_key: None,
}
}
#[inline]
#[must_use]
pub(in crate::value::json_value_encoder) fn tuple_variant(variant: &str, capacity: usize) -> Self {
Self::TupleVariant {
variant: variant.to_owned(),
values: Vec::with_capacity(capacity),
}
}
#[inline]
#[must_use]
pub(in crate::value::json_value_encoder) fn struct_variant(variant: &str, capacity: usize) -> Self {
Self::StructVariant {
variant: variant.to_owned(),
values: Map::with_capacity(capacity),
}
}
#[inline(always)]
#[must_use]
pub(in crate::value::json_value_encoder) const fn raw_value() -> Self {
Self::RawValue { text: None }
}
fn insert(values: &mut Map<String, Value>, key: String, value: Value) -> Result<(), JsonSerializationError> {
if values.contains_key(&key) {
return Err(JsonSerializationError::new(
JsonSerializationErrorKind::DuplicateObjectKey,
));
}
values.insert(key, value);
Ok(())
}
}
impl SerializeSeq for JsonValueCompound {
type Ok = Value;
type Error = JsonSerializationError;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
let Self::Sequence(values) = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
values.push(value.serialize(JsonValueSerializer)?);
Ok(())
}
fn end(self) -> Result<Value, Self::Error> {
let Self::Sequence(values) = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
Ok(Value::Array(values))
}
}
impl SerializeTuple for JsonValueCompound {
type Ok = Value;
type Error = JsonSerializationError;
#[inline(always)]
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
SerializeSeq::serialize_element(self, value)
}
#[inline(always)]
fn end(self) -> Result<Value, Self::Error> {
SerializeSeq::end(self)
}
}
impl SerializeTupleStruct for JsonValueCompound {
type Ok = Value;
type Error = JsonSerializationError;
#[inline(always)]
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
SerializeSeq::serialize_element(self, value)
}
#[inline(always)]
fn end(self) -> Result<Value, Self::Error> {
SerializeSeq::end(self)
}
}
impl SerializeTupleVariant for JsonValueCompound {
type Ok = Value;
type Error = JsonSerializationError;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
let Self::TupleVariant { values, .. } = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
values.push(value.serialize(JsonValueSerializer)?);
Ok(())
}
fn end(self) -> Result<Value, Self::Error> {
let Self::TupleVariant { variant, values } = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
let mut object = Map::new();
object.insert(variant, Value::Array(values));
Ok(Value::Object(object))
}
}
impl SerializeMap for JsonValueCompound {
type Ok = Value;
type Error = JsonSerializationError;
fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
let Self::Map { next_key, .. } = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
if next_key.is_some() {
return Err(invalid_state(JsonSerializerStateError::MapKeyAlreadyPending));
}
*next_key = Some(key.serialize(JsonValueMapKeySerializer)?);
Ok(())
}
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
let Self::Map { values, next_key } = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
let key = next_key
.take()
.ok_or_else(|| invalid_state(JsonSerializerStateError::MapValueWithoutKey))?;
Self::insert(values, key, value.serialize(JsonValueSerializer)?)
}
fn end(self) -> Result<Value, Self::Error> {
let Self::Map { values, next_key } = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
if next_key.is_some() {
return Err(invalid_state(JsonSerializerStateError::MapEndedWithPendingKey));
}
Ok(Value::Object(values))
}
}
impl SerializeStruct for JsonValueCompound {
type Ok = Value;
type Error = JsonSerializationError;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
match self {
Self::Map { values, next_key } => {
if next_key.is_some() {
return Err(invalid_state(JsonSerializerStateError::MapKeyAlreadyPending));
}
Self::insert(values, key.to_owned(), value.serialize(JsonValueSerializer)?)
}
Self::RawValue { text } => {
if key != RAW_VALUE_TOKEN || text.is_some() {
return Err(invalid_state(JsonSerializerStateError::InvalidRawValueProtocol));
}
let Value::String(value) = value.serialize(JsonValueSerializer)? else {
return Err(invalid_state(JsonSerializerStateError::InvalidRawValueProtocol));
};
*text = Some(value);
Ok(())
}
_ => Err(invalid_state(JsonSerializerStateError::UnexpectedCompound)),
}
}
#[inline(always)]
fn end(self) -> Result<Value, Self::Error> {
match self {
Self::Map { values, next_key } => {
if next_key.is_some() {
return Err(invalid_state(JsonSerializerStateError::MapEndedWithPendingKey));
}
Ok(Value::Object(values))
}
Self::RawValue { text: Some(text) } => decode_raw_value(&text),
Self::RawValue { .. } => Err(invalid_state(JsonSerializerStateError::InvalidRawValueProtocol)),
_ => Err(invalid_state(JsonSerializerStateError::UnexpectedCompound)),
}
}
}
impl SerializeStructVariant for JsonValueCompound {
type Ok = Value;
type Error = JsonSerializationError;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
let Self::StructVariant { values, .. } = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
Self::insert(values, key.to_owned(), value.serialize(JsonValueSerializer)?)
}
fn end(self) -> Result<Value, Self::Error> {
let Self::StructVariant { variant, values } = self else {
return Err(invalid_state(JsonSerializerStateError::UnexpectedCompound));
};
let mut object = Map::new();
object.insert(variant, Value::Object(values));
Ok(Value::Object(object))
}
}
#[inline(always)]
fn invalid_state(reason: JsonSerializerStateError) -> JsonSerializationError {
JsonSerializationError::new(JsonSerializationErrorKind::InvalidSerializerState { reason })
}