summary refs log tree commit diff stats
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs566
1 files changed, 561 insertions, 5 deletions
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<D, TransmuteError> {
-    transmute_seed(s, core::marker::PhantomData::<D>, settings)
+    transmute_seed(s, std::marker::PhantomData::<D>, 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<D::Value, TransmuteError> {
-    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: std::fmt::Display>(t: T) -> Self {
+        todo!()
+    }
+}
+
+impl serde::ser::Error for TransmuteError {
+    fn custom<T: std::fmt::Display>(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<Vis: Visitor<'de>>(
+        self,
+        visitor: Vis,
+    ) -> Result<Vis::Value, Self::Error> {
+        todo!()
+    }
+
+    fn deserialize_ignored_any<Vis: Visitor<'de>>(
+        self,
+        visitor: Vis,
+    ) -> Result<Vis::Value, Self::Error> {
+        visitor.visit_unit()
+    }
+
+    serde::forward_to_deserialize_any! {
+        <Vis: Visitor<'de>>
+        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<Self::Ok, Self::Error> {
+        Ok(Collection::Bool(value))
+    }
+    fn serialize_i8(self, value: i8) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::I8(value))
+    }
+    fn serialize_i16(self, value: i16) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::I16(value))
+    }
+    fn serialize_i32(self, value: i32) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::I32(value))
+    }
+    fn serialize_i64(self, value: i64) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::I64(value))
+    }
+    fn serialize_i128(self, value: i128) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::I128(value))
+    }
+    fn serialize_u8(self, value: u8) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::U8(value))
+    }
+    fn serialize_u16(self, value: u16) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::U16(value))
+    }
+    fn serialize_u32(self, value: u32) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::U32(value))
+    }
+    fn serialize_u64(self, value: u64) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::U64(value))
+    }
+    fn serialize_u128(self, value: u128) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::U128(value))
+    }
+    fn serialize_f32(self, value: f32) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::F32(value))
+    }
+    fn serialize_f64(self, value: f64) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::F64(value))
+    }
+    fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::Char(value))
+    }
+    fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::Str(From::from(value)))
+    }
+    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::Bytes(From::from(value)))
+    }
+    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::None)
+    }
+    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize + ?Sized,
+    {
+        value.serialize(self).map(|it| Collection::Some(Box::new(it)))
+    }
+    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::Unit)
+    }
+    fn serialize_unit_struct(
+        self,
+        name: &'static str,
+    ) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::UnitStruct {
+            name
+        })
+    }
+    fn serialize_unit_variant(
+        self,
+        name: &'static str,
+        variant_index: u32,
+        variant: &'static str,
+    ) -> Result<Self::Ok, Self::Error> {
+        Ok(Collection::UnitVariant {
+            name, variant_index, variant
+        })
+    }
+    fn serialize_newtype_struct<T>(
+        self,
+        name: &'static str,
+        value: &T,
+    ) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize + ?Sized,
+    {
+        value.serialize(self).map(|it| Collection::NewtypeStruct {
+            name, value: Box::new(it)
+        })
+    }
+    fn serialize_newtype_variant<T>(
+        self,
+        name: &'static str,
+        variant_index: u32,
+        variant: &'static str,
+        value: &T,
+    ) -> Result<Self::Ok, Self::Error>
+    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<usize>,
+    ) -> Result<Self::SerializeSeq, Self::Error> {
+        Ok(CollectSeq {
+            ser: self,
+            values: len.map_or_else(Vec::new, Vec::with_capacity),
+        })
+    }
+    fn serialize_tuple(
+        self,
+        len: usize,
+    ) -> Result<Self::SerializeTuple, Self::Error> {
+        Ok(CollectTuple {
+            ser: self,
+            len: len,
+            values: Vec::with_capacity(len),
+        })
+    }
+    fn serialize_tuple_struct(
+        self,
+        name: &'static str,
+        len: usize
+    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+        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<Self::SerializeTupleVariant, Self::Error> {
+        Ok(CollectTupleVariant {
+            ser: self,
+            len, name, variant_index, variant,
+            values: Vec::with_capacity(len),
+        })
+    }
+    fn serialize_map(
+        self,
+        len: Option<usize>,
+    ) -> Result<Self::SerializeMap, Self::Error> {
+        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<Self::SerializeStruct, Self::Error> {
+        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<Self::SerializeStructVariant, Self::Error> {
+        Ok(CollectStructVariant {
+            ser: self,
+            len, name, variant_index, variant,
+            values: Vec::with_capacity(len),
+        })
+    }
+}
+
+struct CollectSeq<'settings> {
+    ser: Collect<'settings>,
+    values: Vec<Collection>,
+}
+struct CollectTuple<'settings> {
+    ser: Collect<'settings>,
+    len: usize,
+    values: Vec<Collection>,
+}
+struct CollectTupleStruct<'settings> {
+    ser: Collect<'settings>,
+    name: &'static str,
+    len: usize,
+    values: Vec<Collection>,
+}
+struct CollectTupleVariant<'settings> {
+    ser: Collect<'settings>,
+    name: &'static str,
+    variant: &'static str,
+    variant_index: u32,
+    len: usize,
+    values: Vec<Collection>,
+}
+struct CollectMap<'settings> {
+    ser: Collect<'settings>,
+    values: Vec<(Collection, Collection)>,
+    key: Result<Collection, TransmuteError>,
+}
+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<T>(&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<Self::Ok, Self::Error> {
+        Ok(Collection::Seq(self.values))
+    }
+}
+impl<'settings> serde::ser::SerializeTuple for CollectTuple<'settings> {
+    type Ok = Collection;
+    type Error = TransmuteError;
+    fn serialize_element<T>(&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<Self::Ok, Self::Error> {
+        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<T>(&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<Self::Ok, Self::Error> {
+        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<T>(&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<Self::Ok, Self::Error> {
+        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<T>(
+        &mut self,
+        key: &T,
+    ) -> Result<(), Self::Error>
+    where
+        T: Serialize + ?Sized,
+    {
+        key.serialize(self.ser).map(|it| self.key = Ok(it))
+    }
+    fn serialize_value<T>(
+        &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<Self::Ok, Self::Error> {
+        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<T>(
+        &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<Self::Ok, Self::Error> {
+        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<T>(
+        &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<Self::Ok, Self::Error> {
+        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<str>),
+    Bytes(Vec<u8>),
+    Some(Box<Collection>),
+    None,
+    Unit,
+    UnitStruct {
+        name: &'static str,
+    },
+    UnitVariant {
+        name: &'static str,
+        variant: &'static str,
+        variant_index: u32,
+    },
+    NewtypeStruct {
+        name: &'static str,
+        value: Box<Collection>,
+    },
+    NewtypeVariant {
+        name: &'static str,
+        variant: &'static str,
+        variant_index: u32,
+        value: Box<Collection>,
+    },
+    Seq(Vec<Collection>),
+    Tuple(Vec<Collection>),
+    TupleStruct {
+        name: &'static str,
+        values: Vec<Collection>,
+    },
+    TupleVariant {
+        name: &'static str,
+        variant: &'static str,
+        variant_index: u32,
+        values: Vec<Collection>,
+    },
+    // 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)>,
+    },
+}