diff options
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/lib.rs | 154 |
2 files changed, 149 insertions, 7 deletions
diff --git a/Cargo.toml b/Cargo.toml index 8065cca..703f9a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_transmute" -version = "0.1.2" +version = "0.1.3" edition = "2021" description = "Transmute objects through serde." license = "MIT OR Apache-2.0" diff --git a/src/lib.rs b/src/lib.rs index c15c45b..d254b6f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -194,12 +194,23 @@ impl<'settings, 'de> Deserializer<'de> for Transmute<'settings> { | Collection::TupleStruct { .. } => visitor.visit_seq(self), Collection::Map(_) => { - todo!() + visitor.visit_map(MapAccess { + transmute: self, + // FIXME? + value: Err(TransmuteError(())), + }) } | Collection::StructVariant { .. } | Collection::Struct { .. } => { - todo!() + match self.settings.structs_are_seqs { + false => visitor.visit_map(MapAccess { + transmute: self, + // FIXME? + value: Err(TransmuteError(())), + }), + true => visitor.visit_seq(self), + } } } } @@ -216,8 +227,7 @@ impl<'settings, 'de> Deserializer<'de> for Transmute<'settings> { | Collection::TupleVariant { .. } | Collection::StructVariant { .. } => visitor.visit_enum(self), - // FIXME? - _ => Err(TransmuteError(())), + _ => self.deserialize_any(visitor), } } @@ -240,6 +250,103 @@ impl<'settings, 'de> Deserializer<'de> for Transmute<'settings> { } } +struct MapAccess<'settings> { + transmute: Transmute<'settings>, + value: Result<Collection, TransmuteError>, +} + +impl<'settings, 'de> serde::de::MapAccess<'de> for MapAccess<'settings> { + type Error = TransmuteError; + fn next_key_seed<T>( + &mut self, + seed: T, + ) -> Result<Option<T::Value>, Self::Error> + where + T: DeserializeSeed<'de>, + { + if self.value.is_ok() { + // FIXME? + return Err(TransmuteError(())); + } + match &mut self.transmute.collection { + Collection::Map(values) => { + values.next().map(|(k, v)| { + self.value = Ok(v); + seed.deserialize(Transmute { + settings: self.transmute.settings, + collection: k, + }) + }).transpose() + }, + | Collection::StructVariant { values, .. } + | Collection::Struct { values, .. } + => { + values.next().map(|(k, v)| { + self.value = Ok(v); + seed.deserialize(serde::de::value::StrDeserializer::new(k)) + }).transpose() + }, + _ => unreachable!(), + } + } + fn next_value_seed<T>( + &mut self, + seed: T, + ) -> Result<T::Value, Self::Error> + where + T: DeserializeSeed<'de>, + { + // FIXME? + let v = std::mem::replace(&mut self.value, Err(TransmuteError(()))); + v.and_then(|it| { + seed.deserialize(Transmute { + settings: self.transmute.settings, + collection: it, + }) + }) + } + fn next_entry_seed<K, V>( + &mut self, + key_seed: K, + value_seed: V, + ) -> Result<Option<(K::Value, V::Value)>, Self::Error> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, + { + if self.value.is_ok() { + // FIXME? + return Err(TransmuteError(())); + } + match &mut self.transmute.collection { + Collection::Map(values) => { + values.next().map(|(k, v)| { + key_seed.deserialize(Transmute { + settings: self.transmute.settings, + collection: k, + }).and_then(|k| value_seed.deserialize(Transmute { + settings: self.transmute.settings, + collection: v, + }).map(|v| (k, v))) + }).transpose() + }, + | Collection::StructVariant { values, .. } + | Collection::Struct { values, .. } + => { + values.next().map(|(k, v)| { + key_seed.deserialize( + serde::de::value::StrDeserializer::new(k) + ).and_then(|k| value_seed.deserialize(Transmute { + settings: self.transmute.settings, + collection: v, + }).map(|v| (k, v))) + }).transpose() + }, + _ => unreachable!(), + } + } +} + impl<'settings, 'de> serde::de::SeqAccess<'de> for Transmute<'settings> { type Error = TransmuteError; fn next_element_seed<T>( @@ -255,6 +362,9 @@ impl<'settings, 'de> serde::de::SeqAccess<'de> for Transmute<'settings> { | Collection::TupleVariant { values, .. } | Collection::TupleStruct { values, .. } => values.next(), + | Collection::StructVariant { values, .. } + | Collection::Struct { values, .. } + => values.next().map(|(_, v)| v), _ => unreachable!(), }.map(|value| seed.deserialize(Self { settings: self.settings, @@ -268,6 +378,9 @@ impl<'settings, 'de> serde::de::SeqAccess<'de> for Transmute<'settings> { | Collection::TupleVariant { values, .. } | Collection::TupleStruct { values, .. } => values.size_hint().1, + | Collection::StructVariant { values, .. } + | Collection::Struct { values, .. } + => values.size_hint().1, _ => unreachable!(), } } @@ -371,7 +484,9 @@ impl<'settings, 'de> serde::de::VariantAccess<'de> for Transmute<'settings> { Vis: Visitor<'de>, { match self.collection { - Collection::TupleVariant { .. } => todo!(), + Collection::TupleVariant { .. } => { + visitor.visit_seq(self) + }, _ => { let unexp = match self.collection { Collection::UnitVariant { .. } => { @@ -401,7 +516,16 @@ impl<'settings, 'de> serde::de::VariantAccess<'de> for Transmute<'settings> { Vis: Visitor<'de>, { match self.collection { - Collection::StructVariant { .. } => todo!(), + Collection::StructVariant { .. } => { + match self.settings.structs_are_seqs { + false => visitor.visit_map(MapAccess { + transmute: self, + // FIXME? + value: Err(TransmuteError(())), + }), + true => visitor.visit_seq(self), + } + }, _ => { let unexp = match self.collection { Collection::UnitVariant { .. } => { @@ -782,6 +906,24 @@ impl<'settings> serde::ser::SerializeMap for CollectMap<'settings> { value.serialize(self.ser).map(|it| self.values.push((key, it))) }) } + fn serialize_entry<K, V>( + &mut self, + key: &K, + value: &V, + ) -> Result<(), Self::Error> + where + K: Serialize + ?Sized, + V: Serialize + ?Sized, + { + if self.key.is_ok() { + // FIXME? + Err(TransmuteError(())) + } else { + key.serialize(self.ser).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? |