use crate::error::{Error, Result};
use crate::molecule::{assemble_fixvec, assemble_struct, assemble_table};
use alloc::vec;
use alloc::vec::Vec;
use serde::ser::{self, Serialize};
pub fn to_vec<T>(value: &T, is_struct: bool) -> Result<Vec<u8>>
where
T: ?Sized + Serialize,
{
let mut serializer = MoleculeSerializer::new(is_struct);
value.serialize(&mut serializer)?;
Ok(serializer.into())
}
pub(crate) struct MoleculeSerializer {
data: Vec<u8>,
is_struct: bool,
}
impl MoleculeSerializer {
pub fn new(is_struct: bool) -> Self {
MoleculeSerializer {
data: vec![],
is_struct,
}
}
}
impl From<MoleculeSerializer> for Vec<u8> {
fn from(value: MoleculeSerializer) -> Self {
value.data
}
}
impl MoleculeSerializer {
pub fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
self.data.extend(iter);
}
pub fn is_struct(&self) -> bool {
self.is_struct
}
}
impl<'a> ser::Serializer for &'a mut MoleculeSerializer {
type Ok = ();
type Error = Error;
type SerializeSeq = FixVec<'a>;
type SerializeTuple = Tuple<'a>;
type SerializeStruct = Table<'a>;
type SerializeMap = Map<'a>;
type SerializeStructVariant = Variant<'a>;
type SerializeTupleVariant = Variant<'a>;
type SerializeTupleStruct = Table<'a>;
fn serialize_bool(self, value: bool) -> Result<()> {
let value = match value {
true => 1u8,
false => 0u8,
};
self.data.push(value);
Ok(())
}
fn serialize_i8(self, value: i8) -> Result<()> {
let value = u8::from_le_bytes(value.to_le_bytes());
self.data.push(value);
Ok(())
}
fn serialize_i16(self, value: i16) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_i32(self, value: i32) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_i64(self, value: i64) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_i128(self, value: i128) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_u8(self, value: u8) -> Result<()> {
self.data.push(value);
Ok(())
}
fn serialize_u16(self, value: u16) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_u32(self, value: u32) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_u64(self, value: u64) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_u128(self, value: u128) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_f32(self, value: f32) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_f64(self, value: f64) -> Result<()> {
let value = value.to_le_bytes();
self.data.extend(value);
Ok(())
}
fn serialize_char(self, value: char) -> Result<()> {
let value: u32 = value.into();
self.data.extend(value.to_le_bytes());
Ok(())
}
fn serialize_str(self, value: &str) -> Result<()> {
let len = value.len() as u32;
self.data.extend(len.to_le_bytes());
self.data.extend(value.as_bytes());
Ok(())
}
fn serialize_bytes(self, value: &[u8]) -> Result<()> {
self.data.extend(value);
Ok(())
}
fn serialize_unit(self) -> Result<()> {
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
Err(Error::Unimplemented)
}
fn serialize_unit_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
) -> Result<()> {
self.serialize_u32(variant_index)
}
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<()>
where
T: ?Sized + Serialize,
{
self.serialize_u32(variant_index)?;
value.serialize(self)
}
fn serialize_none(self) -> Result<()> {
Ok(())
}
fn serialize_some<T>(self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
if self.is_struct {
return Err(Error::MixTableAndStruct);
}
Ok(FixVec::new(self))
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Ok(Tuple::new(self))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
Ok(Table::new(self, len, false))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant> {
Ok(Variant::new(self, len, false, variant_index))
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
if self.is_struct {
return Err(Error::MixTableAndStruct);
}
Ok(Map::new(self))
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
Ok(Table::new(self, len, self.is_struct()))
}
fn serialize_struct_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
Ok(Variant::new(self, len, false, variant_index))
}
}
pub(crate) struct FixVec<'a> {
ser: &'a mut MoleculeSerializer,
parts: Vec<Vec<u8>>,
}
impl<'a> FixVec<'a> {
pub fn new(ser: &'a mut MoleculeSerializer) -> Self {
FixVec { ser, parts: vec![] }
}
}
impl ser::SerializeSeq for FixVec<'_> {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.parts.push(to_vec(value, true)?);
Ok(())
}
fn end(self) -> Result<()> {
self.ser.extend(assemble_fixvec(&self.parts)?);
Ok(())
}
}
pub(crate) struct Tuple<'a> {
ser: &'a mut MoleculeSerializer,
data: Vec<u8>,
}
impl<'a> Tuple<'a> {
pub fn new(ser: &'a mut MoleculeSerializer) -> Self {
Self { ser, data: vec![] }
}
}
impl ser::SerializeTuple for Tuple<'_> {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
let data = to_vec(value, true)?;
self.data.extend(data);
Ok(())
}
fn end(self) -> Result<()> {
self.ser.extend(self.data);
Ok(())
}
}
pub(crate) struct Table<'a> {
ser: &'a mut MoleculeSerializer,
parts: Vec<Vec<u8>>,
count: usize,
is_struct: bool,
}
impl<'a> Table<'a> {
pub fn new(ser: &'a mut MoleculeSerializer, count: usize, is_struct: bool) -> Self {
Table {
ser,
parts: vec![],
count,
is_struct,
}
}
}
impl ser::SerializeStruct for Table<'_> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.parts.push(to_vec(value, self.is_struct)?);
Ok(())
}
fn end(self) -> Result<()> {
if self.parts.len() != self.count {
return Err(Error::InvalidTableCount);
}
if self.is_struct {
let data = assemble_struct(self.parts);
self.ser.extend(data);
} else {
let data = assemble_table(&self.parts);
self.ser.extend(data);
}
Ok(())
}
}
impl ser::SerializeTupleStruct for Table<'_> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
ser::SerializeStruct::serialize_field(self, "", value)
}
fn end(self) -> Result<()> {
ser::SerializeStruct::end(self)
}
}
pub(crate) struct Map<'a> {
ser: &'a mut MoleculeSerializer,
parts: Vec<Vec<u8>>,
temp_key: Vec<u8>,
}
impl<'a> Map<'a> {
pub fn new(ser: &'a mut MoleculeSerializer) -> Self {
Self {
ser,
parts: vec![],
temp_key: vec![],
}
}
}
impl ser::SerializeMap for Map<'_> {
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
let mut ser = MoleculeSerializer::new(false);
let result = key.serialize(&mut ser);
self.temp_key = ser.into();
result
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
let mut ser = MoleculeSerializer::new(false);
let result = value.serialize(&mut ser);
let parts = vec![self.temp_key.clone(), ser.into()];
self.parts.push(assemble_table(&parts));
result
}
fn end(self) -> Result<()> {
self.ser.extend(assemble_table(&self.parts));
Ok(())
}
}
pub(crate) struct Variant<'a> {
ser: &'a mut MoleculeSerializer,
parts: Vec<Vec<u8>>,
count: usize,
is_struct: bool,
variant_index: u32,
}
impl<'a> Variant<'a> {
pub fn new(
ser: &'a mut MoleculeSerializer,
count: usize,
is_struct: bool,
variant_index: u32,
) -> Self {
Variant {
ser,
parts: vec![],
count,
is_struct,
variant_index,
}
}
}
impl ser::SerializeStructVariant for Variant<'_> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.parts.push(to_vec(value, self.is_struct)?);
Ok(())
}
fn end(self) -> Result<()> {
if self.parts.len() != self.count {
return Err(Error::InvalidTableCount);
}
if self.is_struct {
return Err(Error::Unimplemented);
}
let data = assemble_table(&self.parts);
self.ser.extend(self.variant_index.to_le_bytes());
self.ser.extend(data);
Ok(())
}
}
impl ser::SerializeTupleVariant for Variant<'_> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
ser::SerializeStructVariant::serialize_field(self, "", value)
}
fn end(self) -> Result<()> {
ser::SerializeStructVariant::end(self)
}
}