From ba324b4f5497065f80d18ed42e0cf31d2ee1e3da Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Mon, 10 Apr 2023 01:49:51 +0100 Subject: [PATCH] Allow deserializing Lua null into unit(`()`) or unit struct. See #264 --- src/serde/de.rs | 24 +++++++++++++++++++++++- tests/serde.rs | 23 ++++++++++++++++++----- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/serde/de.rs b/src/serde/de.rs index 9703005..aab303d 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -345,9 +345,31 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> { } } + #[inline] + fn deserialize_unit(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + Value::LightUserData(ud) if ud.0.is_null() => visitor.visit_unit(), + _ => self.deserialize_any(visitor), + } + } + + #[inline] + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + Value::LightUserData(ud) if ud.0.is_null() => visitor.visit_unit(), + _ => self.deserialize_any(visitor), + } + } + serde::forward_to_deserialize_any! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes - byte_buf unit unit_struct identifier ignored_any + byte_buf identifier ignored_any } } diff --git a/tests/serde.rs b/tests/serde.rs index 27a9b23..c092c43 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -392,31 +392,44 @@ fn test_from_value_newtype_struct() -> Result<(), Box> { #[test] fn test_from_value_enum() -> Result<(), Box> { let lua = Lua::new(); + lua.globals().set("null", lua.null())?; #[derive(Deserialize, PartialEq, Debug)] - enum E { + struct UnitStruct; + + #[derive(Deserialize, PartialEq, Debug)] + enum E { Unit, Integer(u32), Tuple(u32, u32), Struct { a: u32 }, + Wrap(T), } let value = lua.load(r#""Unit""#).eval()?; - let got = lua.from_value(value)?; + let got: E = lua.from_value(value)?; assert_eq!(E::Unit, got); let value = lua.load(r#"{Integer = 1}"#).eval()?; - let got = lua.from_value(value)?; + let got: E = lua.from_value(value)?; assert_eq!(E::Integer(1), got); let value = lua.load(r#"{Tuple = {1, 2}}"#).eval()?; - let got = lua.from_value(value)?; + let got: E = lua.from_value(value)?; assert_eq!(E::Tuple(1, 2), got); let value = lua.load(r#"{Struct = {a = 3}}"#).eval()?; - let got = lua.from_value(value)?; + let got: E = lua.from_value(value)?; assert_eq!(E::Struct { a: 3 }, got); + let value = lua.load(r#"{Wrap = null}"#).eval()?; + let got = lua.from_value(value)?; + assert_eq!(E::Wrap(UnitStruct), got); + + let value = lua.load(r#"{Wrap = null}"#).eval()?; + let got = lua.from_value(value)?; + assert_eq!(E::Wrap(()), got); + Ok(()) }