mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Add encode_empty_tables_as_array serialize option.
This will change the behaviour of encoding empty Lua tables into array instead of map.
This commit is contained in:
@@ -49,6 +49,11 @@ pub struct Options {
|
||||
///
|
||||
/// Default: **false**
|
||||
pub sort_keys: bool,
|
||||
|
||||
/// If true, empty Lua tables will be encoded as array, instead of map.
|
||||
///
|
||||
/// Default: **false**
|
||||
pub encode_empty_tables_as_array: bool,
|
||||
}
|
||||
|
||||
impl Default for Options {
|
||||
@@ -64,6 +69,7 @@ impl Options {
|
||||
deny_unsupported_types: true,
|
||||
deny_recursive_tables: true,
|
||||
sort_keys: false,
|
||||
encode_empty_tables_as_array: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +99,15 @@ impl Options {
|
||||
self.sort_keys = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets [`encode_empty_tables_as_array`] option.
|
||||
///
|
||||
/// [`encode_empty_tables_as_array`]: #structfield.encode_empty_tables_as_array
|
||||
#[must_use]
|
||||
pub const fn encode_empty_tables_as_array(mut self, enabled: bool) -> Self {
|
||||
self.encode_empty_tables_as_array = enabled;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserializer {
|
||||
@@ -141,6 +156,9 @@ impl<'de> serde::Deserializer<'de> for Deserializer {
|
||||
Err(_) => visitor.visit_bytes(&s.as_bytes()),
|
||||
},
|
||||
Value::Table(ref t) if t.raw_len() > 0 || t.is_array() => self.deserialize_seq(visitor),
|
||||
Value::Table(ref t) if self.options.encode_empty_tables_as_array && t.is_empty() => {
|
||||
self.deserialize_seq(visitor)
|
||||
}
|
||||
Value::Table(_) => self.deserialize_map(visitor),
|
||||
Value::LightUserData(ud) if ud.0.is_null() => visitor.visit_none(),
|
||||
Value::UserData(ud) if ud.is_serializable() => {
|
||||
|
||||
+4
-1
@@ -1020,7 +1020,10 @@ impl Serialize for SerializableTable<'_> {
|
||||
|
||||
// Array
|
||||
let len = self.table.raw_len();
|
||||
if len > 0 || self.table.is_array() {
|
||||
if len > 0
|
||||
|| self.table.is_array()
|
||||
|| (self.options.encode_empty_tables_as_array && self.table.is_empty())
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(len))?;
|
||||
let mut serialize_err = None;
|
||||
let res = self.table.for_each_value::<Value>(|value| {
|
||||
|
||||
@@ -700,6 +700,15 @@ impl<'a> SerializableValue<'a> {
|
||||
self.options.sort_keys = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// If true, empty Lua tables will be encoded as array, instead of map.
|
||||
///
|
||||
/// Default: **false**
|
||||
#[must_use]
|
||||
pub const fn encode_empty_tables_as_array(mut self, enabled: bool) -> Self {
|
||||
self.options.encode_empty_tables_as_array = enabled;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
|
||||
@@ -249,6 +249,26 @@ fn test_serialize_same_table_twice() -> LuaResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_empty_table() -> LuaResult<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let table = Value::Table(lua.create_table()?);
|
||||
let json = serde_json::to_string(&table.to_serializable()).unwrap();
|
||||
assert_eq!(json, "{}");
|
||||
|
||||
// Set the option to encode empty tables as array
|
||||
let json = serde_json::to_string(&table.to_serializable().encode_empty_tables_as_array(true)).unwrap();
|
||||
assert_eq!(json, "[]");
|
||||
|
||||
// Check hashmap table with this option
|
||||
table.as_table().unwrap().set("hello", "world")?;
|
||||
let json = serde_json::to_string(&table.to_serializable().encode_empty_tables_as_array(true)).unwrap();
|
||||
assert_eq!(json, r#"{"hello":"world"}"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_value_struct() -> LuaResult<()> {
|
||||
let lua = Lua::new();
|
||||
@@ -667,6 +687,37 @@ fn test_from_value_userdata() -> Result<(), Box<dyn StdError>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_value_empty_table() -> Result<(), Box<dyn StdError>> {
|
||||
let lua = Lua::new();
|
||||
|
||||
// By default we encode empty tables as objects
|
||||
let t = lua.create_table()?;
|
||||
let got = lua.from_value::<serde_json::Value>(Value::Table(t.clone()))?;
|
||||
assert_eq!(got, serde_json::json!({}));
|
||||
|
||||
// Set the option to encode empty tables as array
|
||||
let got = lua
|
||||
.from_value_with::<serde_json::Value>(
|
||||
Value::Table(t.clone()),
|
||||
DeserializeOptions::new().encode_empty_tables_as_array(true),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(got, serde_json::json!([]));
|
||||
|
||||
// Check hashmap table with this option
|
||||
t.raw_set("hello", "world")?;
|
||||
let got = lua
|
||||
.from_value_with::<serde_json::Value>(
|
||||
Value::Table(t),
|
||||
DeserializeOptions::new().encode_empty_tables_as_array(true),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(got, serde_json::json!({"hello": "world"}));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_value_sorted() -> Result<(), Box<dyn StdError>> {
|
||||
let lua = Lua::new();
|
||||
|
||||
Reference in New Issue
Block a user