diff --git a/CHANGELOG.md b/CHANGELOG.md index 1108516a..d7eeb3e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ Compiler requirement * Minimum compiler version is bumped to 1.51. +Bug fixes +--------- + +* `from_dynamic` now supports deserializing `Option`. + Enhancements ------------ diff --git a/src/serde/de.rs b/src/serde/de.rs index a93cdc8c..9ad18f49 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -365,8 +365,15 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { self.type_error() } - fn deserialize_option>(self, _: V) -> Result> { - self.type_error() + fn deserialize_option>( + self, + visitor: V, + ) -> Result> { + if self.value.is::<()>() { + visitor.visit_none() + } else { + visitor.visit_some(self) + } } fn deserialize_unit>(self, visitor: V) -> Result> { diff --git a/tests/serde.rs b/tests/serde.rs index ac98dc37..95bde973 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -746,3 +746,32 @@ fn test_serde_json() -> serde_json::Result<()> { Ok(()) } + +#[test] +#[cfg(not(feature = "no_object"))] +fn test_serde_optional() -> Result<(), Box> { + #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] + struct TestStruct { + foo: Option, + } + + let mut engine = Engine::new(); + engine.register_type_with_name::("TestStruct"); + + let r = engine.eval::("#{ foo: 'a' }")?; + + assert_eq!( + from_dynamic::(&r)?, + TestStruct { foo: Some('a') } + ); + + let r = engine.eval::("#{ foo: () }")?; + + assert_eq!(from_dynamic::(&r)?, TestStruct { foo: None }); + + let r = engine.eval::("#{ }")?; + + assert_eq!(from_dynamic::(&r)?, TestStruct { foo: None }); + + Ok(()) +}