use super::Error;
use super::Serializer;
use super::num::NumEncoder;
use messagepack_core::{Encode as _, encode::MapFormatEncoder, io::IoWrite};
use serde::ser;
pub(super) enum SerializeMap<'a, 'b, W, Num> {
MapWithLen {
ser: &'a mut Serializer<'b, W, Num>,
},
#[cfg(feature = "alloc")]
MapWithoutLen {
ser: &'a mut Serializer<'b, W, Num>,
key_value: Option<crate::value::Value>,
map_values: alloc::vec::Vec<(crate::value::Value, crate::value::Value)>,
},
}
impl<'a, 'b, W, Num> SerializeMap<'a, 'b, W, Num>
where
'b: 'a,
W: IoWrite,
Num: NumEncoder<W>,
{
pub fn new(
ser: &'a mut Serializer<'b, W, Num>,
len: Option<usize>,
) -> Result<Self, Error<W::Error>> {
if let Some(len) = len {
ser.current_length += MapFormatEncoder::new(len).encode(ser.writer)?;
Ok(Self::MapWithLen { ser })
} else {
#[cfg(feature = "alloc")]
{
Ok(Self::MapWithoutLen {
ser,
key_value: None,
map_values: alloc::vec::Vec::new(),
})
}
#[cfg(not(feature = "alloc"))]
{
Err(Error::SeqLenNone)
}
}
}
}
impl<'a, 'b, W, Num> ser::SerializeMap for SerializeMap<'a, 'b, W, Num>
where
'b: 'a,
W: IoWrite,
Num: NumEncoder<W>,
{
type Ok = ();
type Error = Error<W::Error>;
fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: ?Sized + ser::Serialize,
{
match self {
Self::MapWithLen { ser } => key.serialize(ser.as_mut()),
#[cfg(feature = "alloc")]
Self::MapWithoutLen { key_value, .. } => {
*key_value =
Some(crate::value::to_value(key).map_err(crate::ser::error::convert_error)?);
Ok(())
}
}
}
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + ser::Serialize,
{
match self {
Self::MapWithLen { ser } => value.serialize(ser.as_mut()),
#[cfg(feature = "alloc")]
Self::MapWithoutLen {
key_value,
map_values,
..
} => {
let key = key_value.take().ok_or_else(|| -> Self::Error {
serde::ser::Error::custom("`serialize_value` called before `serialize_key`")
})?;
let value =
crate::value::to_value(value).map_err(crate::ser::error::convert_error)?;
map_values.push((key, value));
Ok(())
}
}
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match self {
Self::MapWithLen { .. } => Ok(()),
#[cfg(feature = "alloc")]
Self::MapWithoutLen {
ser,
map_values,
key_value,
} => {
use serde::Serialize;
if key_value.is_some() {
return Err(serde::ser::Error::custom(
"`serialize_key` called but `serialize_value` not called",
));
}
let map = crate::value::Value::Map(map_values);
map.serialize(ser.as_mut())?;
Ok(())
}
}
}
}
impl<'a, 'b, W, Num> ser::SerializeStruct for SerializeMap<'a, 'b, W, Num>
where
'b: 'a,
W: IoWrite,
Num: NumEncoder<W>,
{
type Ok = ();
type Error = Error<W::Error>;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + ser::Serialize,
{
ser::SerializeMap::serialize_entry(self, key, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
ser::SerializeMap::end(self)
}
}
impl<'a, 'b, W, Num> ser::SerializeStructVariant for SerializeMap<'a, 'b, W, Num>
where
'b: 'a,
W: IoWrite,
Num: NumEncoder<W>,
{
type Ok = ();
type Error = Error<W::Error>;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: ?Sized + ser::Serialize,
{
ser::SerializeMap::serialize_entry(self, key, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
ser::SerializeMap::end(self)
}
}