From 91c1fe71412bccdcae14261494b2b0fbcc8269d0 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 4 Sep 2022 02:17:13 -0300 Subject: Add Serializer/Collect machinery --- src/lib.rs | 566 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 561 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 2bcf3e4..a4a1371 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,14 +13,15 @@ //! But we don't care because this crate was built to power parts of `datafu`. //! And it's pretty good at that. -use serde::{Deserialize, de::DeserializeSeed, Serialize}; +use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor}; +use serde::ser::{Serialize, Serializer}; /// Transmutes the given `Serialize` into a stateless `Deserialize`. pub fn transmute<'de, D: Deserialize<'de>, S: Serialize>( s: S, settings: &Settings, ) -> Result { - transmute_seed(s, core::marker::PhantomData::, settings) + transmute_seed(s, std::marker::PhantomData::, settings) } /// Transmutes the given `Serialize` with a stateful `DeserializeSeed`. @@ -29,14 +30,36 @@ pub fn transmute_seed<'de, D: DeserializeSeed<'de>, S: Serialize>( d: D, settings: &Settings, ) -> Result { - todo!() + let collection = s.serialize(Collect::new(settings))?; + d.deserialize(Transmute::new(collection, settings)) } #[derive(Debug)] pub struct TransmuteError(()); +impl std::fmt::Display for TransmuteError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + todo!() + } +} + +impl std::error::Error for TransmuteError { +} + +impl serde::de::Error for TransmuteError { + fn custom(t: T) -> Self { + todo!() + } +} + +impl serde::ser::Error for TransmuteError { + fn custom(t: T) -> Self { + todo!() + } +} + /// Transmutation settings. -#[derive(Copy, Clone, Debug, Default)] +#[derive(Copy, Clone, Debug)] pub struct Settings { /// Whether to use human-readable format. human_readable: bool, @@ -44,6 +67,15 @@ pub struct Settings { structs_are_seqs: bool, } +impl Default for Settings { + fn default() -> Self { + Self { + human_readable: true, + structs_are_seqs: false, + } + } +} + impl Settings { /// Creates a new transmutation settings with the defaults. pub fn new() -> Self { @@ -55,7 +87,7 @@ impl Settings { /// Some data structures may serialize differently for human-readable and /// non-human-readable formats. /// - /// The default is to use non-human-readable transmutation. + /// The default is to use human-readable transmutation. pub fn set_human_readable(&mut self, human_readable: bool) -> &mut Self { self.human_readable = human_readable; self @@ -77,3 +109,527 @@ impl Settings { self } } + +struct Transmute<'settings> { + settings: &'settings Settings, + collection: Collection, +} + +impl<'settings> Transmute<'settings> { + fn new(collection: Collection, settings: &'settings Settings) -> Self { + Self { + collection, settings + } + } +} + +impl<'settings, 'de> Deserializer<'de> for Transmute<'settings> { + type Error = TransmuteError; + + fn deserialize_any>( + self, + visitor: Vis, + ) -> Result { + todo!() + } + + fn deserialize_ignored_any>( + self, + visitor: Vis, + ) -> Result { + visitor.visit_unit() + } + + serde::forward_to_deserialize_any! { + > + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier + } +} + +#[derive(Copy, Clone, Debug)] +struct Collect<'settings> { + settings: &'settings Settings, +} + +impl<'settings> Collect<'settings> { + fn new(settings: &'settings Settings) -> Self { + Self { + settings, + } + } +} + +impl<'settings> Serializer for Collect<'settings> { + type Ok = Collection; + type Error = TransmuteError; + + fn is_human_readable(&self) -> bool { + self.settings.human_readable + } + + type SerializeSeq = CollectSeq<'settings>; + type SerializeTuple = CollectTuple<'settings>; + type SerializeTupleStruct = CollectTupleStruct<'settings>; + type SerializeTupleVariant = CollectTupleVariant<'settings>; + type SerializeMap = CollectMap<'settings>; + type SerializeStruct = CollectStruct<'settings>; + type SerializeStructVariant = CollectStructVariant<'settings>; + + fn serialize_bool(self, value: bool) -> Result { + Ok(Collection::Bool(value)) + } + fn serialize_i8(self, value: i8) -> Result { + Ok(Collection::I8(value)) + } + fn serialize_i16(self, value: i16) -> Result { + Ok(Collection::I16(value)) + } + fn serialize_i32(self, value: i32) -> Result { + Ok(Collection::I32(value)) + } + fn serialize_i64(self, value: i64) -> Result { + Ok(Collection::I64(value)) + } + fn serialize_i128(self, value: i128) -> Result { + Ok(Collection::I128(value)) + } + fn serialize_u8(self, value: u8) -> Result { + Ok(Collection::U8(value)) + } + fn serialize_u16(self, value: u16) -> Result { + Ok(Collection::U16(value)) + } + fn serialize_u32(self, value: u32) -> Result { + Ok(Collection::U32(value)) + } + fn serialize_u64(self, value: u64) -> Result { + Ok(Collection::U64(value)) + } + fn serialize_u128(self, value: u128) -> Result { + Ok(Collection::U128(value)) + } + fn serialize_f32(self, value: f32) -> Result { + Ok(Collection::F32(value)) + } + fn serialize_f64(self, value: f64) -> Result { + Ok(Collection::F64(value)) + } + fn serialize_char(self, value: char) -> Result { + Ok(Collection::Char(value)) + } + fn serialize_str(self, value: &str) -> Result { + Ok(Collection::Str(From::from(value))) + } + fn serialize_bytes(self, value: &[u8]) -> Result { + Ok(Collection::Bytes(From::from(value))) + } + fn serialize_none(self) -> Result { + Ok(Collection::None) + } + fn serialize_some(self, value: &T) -> Result + where + T: Serialize + ?Sized, + { + value.serialize(self).map(|it| Collection::Some(Box::new(it))) + } + fn serialize_unit(self) -> Result { + Ok(Collection::Unit) + } + fn serialize_unit_struct( + self, + name: &'static str, + ) -> Result { + Ok(Collection::UnitStruct { + name + }) + } + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(Collection::UnitVariant { + name, variant_index, variant + }) + } + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result + where + T: Serialize + ?Sized, + { + value.serialize(self).map(|it| Collection::NewtypeStruct { + name, value: Box::new(it) + }) + } + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: Serialize + ?Sized, + { + value.serialize(self).map(|it| Collection::NewtypeVariant { + name, variant_index, variant, value: Box::new(it) + }) + } + fn serialize_seq( + self, + len: Option, + ) -> Result { + Ok(CollectSeq { + ser: self, + values: len.map_or_else(Vec::new, Vec::with_capacity), + }) + } + fn serialize_tuple( + self, + len: usize, + ) -> Result { + Ok(CollectTuple { + ser: self, + len: len, + values: Vec::with_capacity(len), + }) + } + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize + ) -> Result { + Ok(CollectTupleStruct { + ser: self, + len: len, + name: name, + values: Vec::with_capacity(len), + }) + } + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(CollectTupleVariant { + ser: self, + len, name, variant_index, variant, + values: Vec::with_capacity(len), + }) + } + fn serialize_map( + self, + len: Option, + ) -> Result { + Ok(CollectMap { + ser: self, + values: len.map_or_else(Vec::new, Vec::with_capacity), + // FIXME? + key: Err(TransmuteError(())), + }) + } + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + Ok(CollectStruct { + ser: self, + len: len, + name: name, + values: Vec::with_capacity(len), + }) + } + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(CollectStructVariant { + ser: self, + len, name, variant_index, variant, + values: Vec::with_capacity(len), + }) + } +} + +struct CollectSeq<'settings> { + ser: Collect<'settings>, + values: Vec, +} +struct CollectTuple<'settings> { + ser: Collect<'settings>, + len: usize, + values: Vec, +} +struct CollectTupleStruct<'settings> { + ser: Collect<'settings>, + name: &'static str, + len: usize, + values: Vec, +} +struct CollectTupleVariant<'settings> { + ser: Collect<'settings>, + name: &'static str, + variant: &'static str, + variant_index: u32, + len: usize, + values: Vec, +} +struct CollectMap<'settings> { + ser: Collect<'settings>, + values: Vec<(Collection, Collection)>, + key: Result, +} +struct CollectStruct<'settings> { + ser: Collect<'settings>, + name: &'static str, + len: usize, + values: Vec<(&'static str, Collection)>, +} +struct CollectStructVariant<'settings> { + ser: Collect<'settings>, + name: &'static str, + variant: &'static str, + variant_index: u32, + len: usize, + values: Vec<(&'static str, Collection)>, +} + +impl<'settings> serde::ser::SerializeSeq for CollectSeq<'settings> { + type Ok = Collection; + type Error = TransmuteError; + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + value.serialize(self.ser).map(|it| self.values.push(it)) + } + fn end(self) -> Result { + Ok(Collection::Seq(self.values)) + } +} +impl<'settings> serde::ser::SerializeTuple for CollectTuple<'settings> { + type Ok = Collection; + type Error = TransmuteError; + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + value.serialize(self.ser).map(|it| self.values.push(it)) + } + fn end(self) -> Result { + if self.values.len() != self.len { + // FIXME? + Err(TransmuteError(())) + } else { + Ok(Collection::Tuple(self.values)) + } + } +} +impl<'settings> serde::ser::SerializeTupleStruct for CollectTupleStruct<'settings> { + type Ok = Collection; + type Error = TransmuteError; + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + value.serialize(self.ser).map(|it| self.values.push(it)) + } + fn end(self) -> Result { + if self.values.len() != self.len { + // FIXME? + Err(TransmuteError(())) + } else { + Ok(Collection::TupleStruct { + name: self.name, + values: self.values + }) + } + } +} +impl<'settings> serde::ser::SerializeTupleVariant for CollectTupleVariant<'settings> { + type Ok = Collection; + type Error = TransmuteError; + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + value.serialize(self.ser).map(|it| self.values.push(it)) + } + fn end(self) -> Result { + if self.values.len() != self.len { + // FIXME? + Err(TransmuteError(())) + } else { + Ok(Collection::TupleVariant { + name: self.name, + variant: self.variant, + variant_index: self.variant_index, + values: self.values + }) + } + } +} +impl<'settings> serde::ser::SerializeMap for CollectMap<'settings> { + type Ok = Collection; + type Error = TransmuteError; + fn serialize_key( + &mut self, + key: &T, + ) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + key.serialize(self.ser).map(|it| self.key = Ok(it)) + } + fn serialize_value( + &mut self, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + // FIXME? + let key = std::mem::replace(&mut self.key, Err(TransmuteError(()))); + key.and_then(|key| { + value.serialize(self.ser).map(|it| self.values.push((key, it))) + }) + } + fn end(self) -> Result { + if self.key.is_ok() { + // FIXME? + Err(TransmuteError(())) + } else { + Ok(Collection::Map(self.values)) + } + } +} +impl<'settings> serde::ser::SerializeStruct for CollectStruct<'settings> { + type Ok = Collection; + type Error = TransmuteError; + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + value.serialize(self.ser).map(|it| self.values.push((key, it))) + } + fn end(self) -> Result { + if self.values.len() != self.len { + // FIXME? + Err(TransmuteError(())) + } else { + Ok(Collection::Struct { + name: self.name, + values: self.values + }) + } + } +} +impl<'settings> serde::ser::SerializeStructVariant for CollectStructVariant<'settings> { + type Ok = Collection; + type Error = TransmuteError; + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize + ?Sized, + { + value.serialize(self.ser).map(|it| self.values.push((key, it))) + } + fn end(self) -> Result { + if self.values.len() != self.len { + // FIXME? + Err(TransmuteError(())) + } else { + Ok(Collection::StructVariant { + name: self.name, + variant: self.variant, + variant_index: self.variant_index, + values: self.values + }) + } + } +} + +/// Types serialized by serde. Refer to `Serializer` for details. +#[derive(Debug)] +enum Collection { + Bool(bool), + I8(i8), + I16(i16), + I32(i32), + I64(i64), + I128(i128), + U8(u8), + U16(u16), + U32(u32), + U64(u64), + U128(u128), + F32(f32), + F64(f64), + Char(char), + Str(Box), + Bytes(Vec), + Some(Box), + None, + Unit, + UnitStruct { + name: &'static str, + }, + UnitVariant { + name: &'static str, + variant: &'static str, + variant_index: u32, + }, + NewtypeStruct { + name: &'static str, + value: Box, + }, + NewtypeVariant { + name: &'static str, + variant: &'static str, + variant_index: u32, + value: Box, + }, + Seq(Vec), + Tuple(Vec), + TupleStruct { + name: &'static str, + values: Vec, + }, + TupleVariant { + name: &'static str, + variant: &'static str, + variant_index: u32, + values: Vec, + }, + // NOTE: support for multimaps! + Map(Vec<(Collection, Collection)>), + Struct { + name: &'static str, + values: Vec<(&'static str, Collection)>, + }, + StructVariant { + name: &'static str, + variant: &'static str, + variant_index: u32, + values: Vec<(&'static str, Collection)>, + }, +} -- cgit 1.4.1