nettext/src/serde/ser.rs

370 lines
8.9 KiB
Rust

use serde::{ser, Serialize};
use crate::enc::*;
use crate::serde::error::{Error, Result};
use serde::ser::Error as SerError;
/// Serde serializer for nettext
pub struct Serializer;
/// Serialize value to nettext encoder term
pub fn to_term<T>(value: &T) -> Result<Term<'static>>
where
T: Serialize,
{
value.serialize(&mut Serializer)
}
/// Serialize value to nettext
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
Ok(value.serialize(&mut Serializer)?.encode())
}
impl<'a> ser::Serializer for &'a mut Serializer {
type Ok = Term<'static>;
type Error = Error;
type SerializeSeq = ListSerializer;
type SerializeTuple = SeqSerializer;
type SerializeTupleStruct = SeqSerializer;
type SerializeTupleVariant = SeqSerializer;
type SerializeMap = MapSerializer;
type SerializeStruct = StructSerializer;
type SerializeStructVariant = StructVariantSerializer;
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
Ok(if v {
safe_raw(b"true")
} else {
safe_raw(b"false")
})
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
self.serialize_i64(i64::from(v))
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
self.serialize_i64(i64::from(v))
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
self.serialize_i64(i64::from(v))
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
Ok(safe_raw_owned(v.to_string().into_bytes()))
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
self.serialize_u64(u64::from(v))
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
self.serialize_u64(u64::from(v))
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
self.serialize_u64(u64::from(v))
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
Ok(safe_raw_owned(v.to_string().into_bytes()))
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
self.serialize_f64(f64::from(v))
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
Ok(string_owned(v.to_string())?)
}
fn serialize_char(self, v: char) -> Result<Self::Ok> {
self.serialize_str(&v.to_string())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
Ok(bytes(v.as_bytes()))
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
Ok(bytes(v))
}
fn serialize_none(self) -> Result<Self::Ok> {
Ok(dict([])?)
}
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
where
T: ?Sized + Serialize,
{
Ok(value.serialize(self)?)
}
fn serialize_unit(self) -> Result<Self::Ok> {
Ok(dict([])?)
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
Ok(string(name)?)
}
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok> {
Ok(string_owned(format!("{}.{}", name, variant))?)
}
fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Self::Ok>
where
T: ?Sized + Serialize,
{
Ok(seq_flatten([string(name)?, value.serialize(self)?]))
}
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok>
where
T: ?Sized + Serialize,
{
Ok(seq_flatten([
string_owned(format!("{}.{}", name, variant))?,
value.serialize(self)?,
]))
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Ok(ListSerializer { items: vec![] })
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
Ok(SeqSerializer {
items: Vec::with_capacity(len),
})
}
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
let mut items = Vec::with_capacity(len + 1);
items.push(string(name)?);
Ok(SeqSerializer { items })
}
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant> {
let mut items = Vec::with_capacity(len + 1);
items.push(string_owned(format!("{}.{}", name, variant))?);
Ok(SeqSerializer { items })
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Ok(MapSerializer {
next: None,
fields: vec![],
})
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
Ok(StructSerializer {
name,
fields: Vec::with_capacity(len),
})
}
fn serialize_struct_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
Ok(StructVariantSerializer {
name,
variant,
fields: Vec::with_capacity(len),
})
}
}
// -- sub-serializers --
pub struct SeqSerializer {
items: Vec<Term<'static>>,
}
impl ser::SerializeTuple for SeqSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(seq(self.items.into_iter())?)
}
}
impl ser::SerializeTupleStruct for SeqSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(seq(self.items.into_iter())?)
}
}
impl ser::SerializeTupleVariant for SeqSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(seq(self.items.into_iter())?)
}
}
pub struct ListSerializer {
items: Vec<Term<'static>>,
}
impl ser::SerializeSeq for ListSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.items.push(value.serialize(&mut Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(list(self.items.into_iter()))
}
}
pub struct MapSerializer {
next: Option<Vec<u8>>,
fields: Vec<(Vec<u8>, Term<'static>)>,
}
impl ser::SerializeMap for MapSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.next = Some(key.serialize(&mut Serializer)?.encode());
Ok(())
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.fields.push((
self.next
.take()
.ok_or_else(|| Self::Error::custom("no key"))?,
value.serialize(&mut Serializer)?,
));
Ok(())
}
fn end(self) -> Result<Term<'static>> {
Ok(dict_owned_u8(self.fields.into_iter())?)
}
}
pub struct StructSerializer {
name: &'static str,
fields: Vec<(&'static str, Term<'static>)>,
}
impl ser::SerializeStruct for StructSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.fields.push((key, value.serialize(&mut Serializer)?));
Ok(())
}
fn end(self) -> Result<Term<'static>> {
Ok(seq([string(self.name)?, dict(self.fields.into_iter())?])?)
}
}
pub struct StructVariantSerializer {
name: &'static str,
variant: &'static str,
fields: Vec<(&'static str, Term<'static>)>,
}
impl ser::SerializeStructVariant for StructVariantSerializer {
type Ok = Term<'static>;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.fields.push((key, value.serialize(&mut Serializer)?));
Ok(())
}
fn end(self) -> Result<Term<'static>> {
Ok(seq([
string_owned(format!("{}.{}", self.name, self.variant))?,
dict(self.fields.into_iter())?,
])?)
}
}