nettext 0.4.1

A text-based data format for cryptographic network protocols
Documentation
use serde::{ser, Serialize};

use crate::enc::*;
use crate::serde::error::{Error, Result};
use serde::ser::Error as SerError;

/// Serde serializer for nettext
#[derive(Clone, Copy, Default)]
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::default())
}

/// Serialize value to nettext
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where
    T: Serialize,
{
    Ok(value.serialize(&mut Serializer::default())?.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![],
            ser: *self,
        })
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
        Ok(SeqSerializer {
            items: Vec::with_capacity(len),
            ser: *self,
        })
    }

    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, ser: *self })
    }

    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, ser: *self })
    }

    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
        Ok(MapSerializer {
            next: None,
            fields: vec![],
            ser: *self,
        })
    }

    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
        Ok(StructSerializer {
            name,
            fields: Vec::with_capacity(len),
            ser: *self,
        })
    }

    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),
            ser: *self,
        })
    }
}

// -- sub-serializers --

pub struct SeqSerializer {
    items: Vec<Term<'static>>,
    ser: Serializer,
}

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 self.ser)?);
        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 self.ser)?);
        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 self.ser)?);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(seq(self.items.into_iter())?)
    }
}

pub struct ListSerializer {
    items: Vec<Term<'static>>,
    ser: Serializer,
}
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 self.ser)?);
        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>)>,
    ser: Serializer,
}

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,
    {
        let mut ser = Serializer;
        self.next = Some(key.serialize(&mut ser)?.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 self.ser)?,
        ));
        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>)>,
    ser: Serializer,
}

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 self.ser)?));
        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>)>,
    ser: Serializer,
}

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 self.ser)?));
        Ok(())
    }

    fn end(self) -> Result<Term<'static>> {
        Ok(seq([
            string_owned(format!("{}.{}", self.name, self.variant))?,
            dict(self.fields.into_iter())?,
        ])?)
    }
}