polywrap_msgpack_serde 0.0.2-beta.6

An msgpack Serializer and Deserializer data format with Serde for Polywrap
Documentation
use std::io::Write;

use byteorder::{BigEndian, WriteBytesExt};
use serde::{ser, Serialize};

use crate::{
    error::{Error},
    format::{ExtensionType, Format}, Serializer,
};

pub struct MapSerializer<'a> {
    map_serializer: Serializer,
    map_entries: u32,
    parent_encoder: &'a mut Serializer,
}

impl<'a> MapSerializer<'a> {
    pub fn new(serializer: &'a mut Serializer) -> Self {
        Self {
            parent_encoder: serializer,
            map_serializer: Serializer::default(),
            map_entries: 0,
        }
    }

    pub fn write_map_length<W: Write>(
        writer: &mut W,
        length: &u32,
    ) -> std::result::Result<(), Error> {
        let length = *length;
        if length < 16 {
            Format::set_format(writer, Format::FixMap(length as u8))?;
        } else if length <= u16::MAX as u32 {
            Format::set_format(writer, Format::Map16)?;
            WriteBytesExt::write_u16::<BigEndian>(writer, length as u16)?;
        } else {
            Format::set_format(writer, Format::Map32)?;
            WriteBytesExt::write_u32::<BigEndian>(writer, length)?;
        }
        Ok(())
    }

    pub fn write_ext_map_type<W: Write>(
        writer: &mut W,
    ) -> Result<(), Error> {
        Ok(WriteBytesExt::write_u8(
            writer,
            ExtensionType::GenericMap.into(),
        )?)
    }

    pub fn write_ext_map_len<W: Write>(
        writer: &mut W,
        length: usize,
    ) -> std::result::Result<(), Error> {
        if length <= u8::MAX as usize {
            Format::set_format(writer, Format::Ext8)?;
            WriteBytesExt::write_u8(writer, length.try_into().unwrap())?;
        } else if length <= u16::MAX as usize {
            Format::set_format(writer, Format::Ext16)?;
            WriteBytesExt::write_u16::<BigEndian>(
                writer,
                length.try_into().unwrap(),
            )?;
        } else {
            Format::set_format(writer, Format::Ext32)?;
            WriteBytesExt::write_u32::<BigEndian>(
                writer,
                length.try_into().unwrap(),
            )?;
        }

        Ok(())
    }
}

impl ser::SerializeMap for MapSerializer<'_> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized>(
        &mut self,
        key: &T,
    ) -> std::result::Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut self.map_serializer)?;
        self.map_entries += 1;

        Ok(())
    }

    fn serialize_value<T: ?Sized>(
        &mut self,
        value: &T,
    ) -> std::result::Result<(), Self::Error>
    where
        T: Serialize,
    {
        value.serialize(&mut self.map_serializer)
    }

    fn end(self) -> std::result::Result<Self::Ok, Self::Error> {
        let mut aux_map_encoder = Serializer::default();
        MapSerializer::write_map_length(
            &mut aux_map_encoder,
            &self.map_entries,
        )?;

        aux_map_encoder.write_all(&self.map_serializer.get_buffer())?;

        let map_buffer = aux_map_encoder.get_buffer();

        MapSerializer::write_ext_map_len(
            self.parent_encoder,
            map_buffer.len(),
        )?;
        MapSerializer::write_ext_map_type(self.parent_encoder)?;
        self.parent_encoder.write_all(&map_buffer)?;
        Ok(())
    }
}