Support Option in from_dynamic.

This commit is contained in:
Stephen Chung 2021-12-02 12:50:11 +08:00
parent 5003d836d9
commit 5363b0724f
3 changed files with 43 additions and 2 deletions

View File

@ -9,6 +9,11 @@ Compiler requirement
* Minimum compiler version is bumped to 1.51.
Bug fixes
---------
* `from_dynamic` now supports deserializing `Option`.
Enhancements
------------

View File

@ -365,8 +365,15 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
self.type_error()
}
fn deserialize_option<V: Visitor<'de>>(self, _: V) -> Result<V::Value, Box<EvalAltResult>> {
self.type_error()
fn deserialize_option<V: Visitor<'de>>(
self,
visitor: V,
) -> Result<V::Value, Box<EvalAltResult>> {
if self.value.is::<()>() {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {

View File

@ -746,3 +746,32 @@ fn test_serde_json() -> serde_json::Result<()> {
Ok(())
}
#[test]
#[cfg(not(feature = "no_object"))]
fn test_serde_optional() -> Result<(), Box<EvalAltResult>> {
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
struct TestStruct {
foo: Option<char>,
}
let mut engine = Engine::new();
engine.register_type_with_name::<TestStruct>("TestStruct");
let r = engine.eval::<Dynamic>("#{ foo: 'a' }")?;
assert_eq!(
from_dynamic::<TestStruct>(&r)?,
TestStruct { foo: Some('a') }
);
let r = engine.eval::<Dynamic>("#{ foo: () }")?;
assert_eq!(from_dynamic::<TestStruct>(&r)?, TestStruct { foo: None });
let r = engine.eval::<Dynamic>("#{ }")?;
assert_eq!(from_dynamic::<TestStruct>(&r)?, TestStruct { foo: None });
Ok(())
}