Allow deserializing Lua null into unit(`()`) or unit struct. See #264

This commit is contained in:
Alex Orlenko 2023-04-10 01:49:51 +01:00
parent 3e83753466
commit ba324b4f54
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
2 changed files with 41 additions and 6 deletions

View File

@ -345,9 +345,31 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
} }
} }
#[inline]
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
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<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
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! { serde::forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes 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
} }
} }

View File

@ -392,31 +392,44 @@ fn test_from_value_newtype_struct() -> Result<(), Box<dyn StdError>> {
#[test] #[test]
fn test_from_value_enum() -> Result<(), Box<dyn StdError>> { fn test_from_value_enum() -> Result<(), Box<dyn StdError>> {
let lua = Lua::new(); let lua = Lua::new();
lua.globals().set("null", lua.null())?;
#[derive(Deserialize, PartialEq, Debug)] #[derive(Deserialize, PartialEq, Debug)]
enum E { struct UnitStruct;
#[derive(Deserialize, PartialEq, Debug)]
enum E<T = ()> {
Unit, Unit,
Integer(u32), Integer(u32),
Tuple(u32, u32), Tuple(u32, u32),
Struct { a: u32 }, Struct { a: u32 },
Wrap(T),
} }
let value = lua.load(r#""Unit""#).eval()?; 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); assert_eq!(E::Unit, got);
let value = lua.load(r#"{Integer = 1}"#).eval()?; 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); assert_eq!(E::Integer(1), got);
let value = lua.load(r#"{Tuple = {1, 2}}"#).eval()?; 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); assert_eq!(E::Tuple(1, 2), got);
let value = lua.load(r#"{Struct = {a = 3}}"#).eval()?; 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); 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(()) Ok(())
} }