fully adapt to mlua

This commit is contained in:
Cadey Ratio 2020-07-05 20:57:24 -04:00
parent 9d12a4fc4b
commit 964efbbc73
5 changed files with 259 additions and 188 deletions

View File

@ -1,22 +1,22 @@
# rlue_serde # rlue_serde
Implementation of [serde](https://serde.rs/) Serializer/Deserializer for [rlua::Value](https://docs.rs/rlua/0.12/rlua/enum.Value.html) Implementation of [serde](https://serde.rs/) Serializer/Deserializer for [mlua::Value](https://docs.rs/mlua/0.12/mlua/enum.Value.html)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Crates.io](https://img.shields.io/crates/v/rlua_serde.svg)](https://crates.io/crates/rlua_serde) [![Crates.io](https://img.shields.io/crates/v/mlua_serde.svg)](https://crates.io/crates/mlua_serde)
[![Documentation](https://docs.rs/rlua_serde/badge.svg)][dox] [![Documentation](https://docs.rs/mlua_serde/badge.svg)][dox]
More information about this crate can be found in the [crate documentation][dox]. More information about this crate can be found in the [crate documentation][dox].
[dox]: https://docs.rs/rlua_serde/*/rlua_serde/ [dox]: https://docs.rs/mlua_serde/*/mlua_serde/
## Usage ## Usage
To use `rlua_serde`, first add this to your `Cargo.toml`: To use `mlua_serde`, first add this to your `Cargo.toml`:
```toml ```toml
[dependencies] [dependencies]
rlua_serde = "0.4" mlua_serde = "0.4"
``` ```
Next, you can use `to_value`/`from_value` functions to serialize/deserialize: Next, you can use `to_value`/`from_value` functions to serialize/deserialize:
@ -29,20 +29,18 @@ struct Foo {
} }
fn main() { fn main() {
let lua = rlua::Lua::new(); let lua = mlua::Lua::new();
lua.context(|lua| { let foo = Foo {
let foo = Foo { bar: 42,
bar: 42, baz: vec![String::from("fizz"), String::from("buzz")],
baz: vec![String::from("fizz"), String::from("buzz")], };
};
let value = rlua_serde::to_value(lua, &foo).unwrap(); let value = mlua_serde::to_value(lua, &foo).unwrap();
lua.globals().set("value", value).unwrap(); lua.globals().set("value", value).unwrap();
lua.load( lua.load(
r#" r#"
assert(value["bar"] == 42) assert(value["bar"] == 42)
assert(value["baz"][2] == "buzz") assert(value["baz"][2] == "buzz")
"#).exec().unwrap(); "#).exec().unwrap();
});
} }
``` ```

View File

@ -3,6 +3,6 @@ let
in in
pkgs.mkShell { pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
rustc cargo rls lua5_3 pkg-config rustc cargo rls lua5_3 pkg-config rustfmt
]; ];
} }

201
src/de.rs
View File

@ -1,11 +1,10 @@
use serde; use serde;
use serde::de::IntoDeserializer; use serde::de::IntoDeserializer;
use mlua::{Value, TablePairs, TableSequence}; use mlua::{TablePairs, TableSequence, Value};
use error::{Error, Result}; use error::{Error, Result};
pub struct Deserializer<'lua> { pub struct Deserializer<'lua> {
pub value: Value<'lua>, pub value: Value<'lua>,
} }
@ -15,7 +14,8 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
#[inline] #[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de> where
V: serde::de::Visitor<'de>,
{ {
match self.value { match self.value {
Value::Nil => visitor.visit_unit(), Value::Nil => visitor.visit_unit(),
@ -31,16 +31,20 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
if remaining == 0 { if remaining == 0 {
Ok(map) Ok(map)
} else { } else {
Err(serde::de::Error::invalid_length(len, &"fewer elements in array")) Err(serde::de::Error::invalid_length(
len,
&"fewer elements in array",
))
} }
}, }
_ => Err(serde::de::Error::custom("invalid value type")), _ => Err(serde::de::Error::custom("invalid value type")),
} }
} }
#[inline] #[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de> where
V: serde::de::Visitor<'de>,
{ {
match self.value { match self.value {
Value::Nil => visitor.visit_none(), Value::Nil => visitor.visit_none(),
@ -50,26 +54,32 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
#[inline] #[inline]
fn deserialize_enum<V>( fn deserialize_enum<V>(
self, _name: &str, _variants: &'static [&'static str], visitor: V self,
_name: &str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value> ) -> Result<V::Value>
where V: serde::de::Visitor<'de> where
V: serde::de::Visitor<'de>,
{ {
let (variant, value) = match self.value { let (variant, value) = match self.value {
Value::Table(value) => { Value::Table(value) => {
let mut iter = value.pairs::<String, Value>(); let mut iter = value.pairs::<String, Value>();
let (variant, value) = match iter.next() { let (variant, value) = match iter.next() {
Some(v) => v?, Some(v) => v?,
None => return Err(serde::de::Error::invalid_value( None => {
serde::de::Unexpected::Map, return Err(serde::de::Error::invalid_value(
&"map with a single key", serde::de::Unexpected::Map,
)), &"map with a single key",
))
}
}; };
if iter.next().is_some() { if iter.next().is_some() {
return Err(serde::de::Error::invalid_value( return Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Map, serde::de::Unexpected::Map,
&"map with a single key", &"map with a single key",
)) ));
} }
(variant, Some(value)) (variant, Some(value))
} }
@ -82,7 +92,8 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
#[inline] #[inline]
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de> where
V: serde::de::Visitor<'de>,
{ {
match self.value { match self.value {
Value::Table(v) => { Value::Table(v) => {
@ -93,7 +104,10 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
if remaining == 0 { if remaining == 0 {
Ok(seq) Ok(seq)
} else { } else {
Err(serde::de::Error::invalid_length(len, &"fewer elements in array")) Err(serde::de::Error::invalid_length(
len,
&"fewer elements in array",
))
} }
} }
_ => Err(serde::de::Error::custom("invalid value type")), _ => Err(serde::de::Error::custom("invalid value type")),
@ -102,14 +116,21 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
#[inline] #[inline]
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value> fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de> where
V: serde::de::Visitor<'de>,
{ {
self.deserialize_seq(visitor) self.deserialize_seq(visitor)
} }
#[inline] #[inline]
fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, visitor: V) -> Result<V::Value> fn deserialize_tuple_struct<V>(
where V: serde::de::Visitor<'de> self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value>
where
V: serde::de::Visitor<'de>,
{ {
self.deserialize_seq(visitor) self.deserialize_seq(visitor)
} }
@ -121,19 +142,18 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
} }
} }
struct SeqDeserializer<'lua>(TableSequence<'lua, Value<'lua>>); struct SeqDeserializer<'lua>(TableSequence<'lua, Value<'lua>>);
impl<'lua, 'de> serde::de::SeqAccess<'de> for SeqDeserializer<'lua> { impl<'lua, 'de> serde::de::SeqAccess<'de> for SeqDeserializer<'lua> {
type Error = Error; type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where T: serde::de::DeserializeSeed<'de> where
T: serde::de::DeserializeSeed<'de>,
{ {
match self.0.next() { match self.0.next() {
Some(value) => seed.deserialize(Deserializer { value: value? }) Some(value) => seed.deserialize(Deserializer { value: value? }).map(Some),
.map(Some), None => Ok(None),
None => Ok(None)
} }
} }
@ -145,17 +165,17 @@ impl<'lua, 'de> serde::de::SeqAccess<'de> for SeqDeserializer<'lua> {
} }
} }
struct MapDeserializer<'lua>( struct MapDeserializer<'lua>(
TablePairs<'lua, Value<'lua>, Value<'lua>>, TablePairs<'lua, Value<'lua>, Value<'lua>>,
Option<Value<'lua>> Option<Value<'lua>>,
); );
impl<'lua, 'de> serde::de::MapAccess<'de> for MapDeserializer<'lua> { impl<'lua, 'de> serde::de::MapAccess<'de> for MapDeserializer<'lua> {
type Error = Error; type Error = Error;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where T: serde::de::DeserializeSeed<'de> where
T: serde::de::DeserializeSeed<'de>,
{ {
match self.0.next() { match self.0.next() {
Some(item) => { Some(item) => {
@ -163,13 +183,14 @@ impl<'lua, 'de> serde::de::MapAccess<'de> for MapDeserializer<'lua> {
self.1 = Some(value); self.1 = Some(value);
let key_de = Deserializer { value: key }; let key_de = Deserializer { value: key };
seed.deserialize(key_de).map(Some) seed.deserialize(key_de).map(Some)
}, }
None => Ok(None), None => Ok(None),
} }
} }
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value> fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value>
where T: serde::de::DeserializeSeed<'de> where
T: serde::de::DeserializeSeed<'de>,
{ {
match self.1.take() { match self.1.take() {
Some(value) => seed.deserialize(Deserializer { value }), Some(value) => seed.deserialize(Deserializer { value }),
@ -185,7 +206,6 @@ impl<'lua, 'de> serde::de::MapAccess<'de> for MapDeserializer<'lua> {
} }
} }
struct EnumDeserializer<'lua> { struct EnumDeserializer<'lua> {
variant: String, variant: String,
value: Option<Value<'lua>>, value: Option<Value<'lua>>,
@ -196,7 +216,8 @@ impl<'lua, 'de> serde::de::EnumAccess<'de> for EnumDeserializer<'lua> {
type Variant = VariantDeserializer<'lua>; type Variant = VariantDeserializer<'lua>;
fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant)> fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant)>
where T: serde::de::DeserializeSeed<'de> where
T: serde::de::DeserializeSeed<'de>,
{ {
let variant = self.variant.into_deserializer(); let variant = self.variant.into_deserializer();
let variant_access = VariantDeserializer { value: self.value }; let variant_access = VariantDeserializer { value: self.value };
@ -204,7 +225,6 @@ impl<'lua, 'de> serde::de::EnumAccess<'de> for EnumDeserializer<'lua> {
} }
} }
struct VariantDeserializer<'lua> { struct VariantDeserializer<'lua> {
value: Option<Value<'lua>>, value: Option<Value<'lua>>,
} }
@ -218,49 +238,46 @@ impl<'lua, 'de> serde::de::VariantAccess<'de> for VariantDeserializer<'lua> {
serde::de::Unexpected::NewtypeVariant, serde::de::Unexpected::NewtypeVariant,
&"unit variant", &"unit variant",
)), )),
None => Ok(()) None => Ok(()),
} }
} }
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where T: serde::de::DeserializeSeed<'de> where
T: serde::de::DeserializeSeed<'de>,
{ {
match self.value { match self.value {
Some(value) => seed.deserialize(Deserializer { value }), Some(value) => seed.deserialize(Deserializer { value }),
None => Err(serde::de::Error::invalid_type( None => Err(serde::de::Error::invalid_type(
serde::de::Unexpected::UnitVariant, serde::de::Unexpected::UnitVariant,
&"newtype variant", &"newtype variant",
)) )),
} }
} }
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de> where
V: serde::de::Visitor<'de>,
{ {
match self.value { match self.value {
Some(value) => serde::Deserializer::deserialize_seq( Some(value) => serde::Deserializer::deserialize_seq(Deserializer { value }, visitor),
Deserializer { value }, visitor
),
None => Err(serde::de::Error::invalid_type( None => Err(serde::de::Error::invalid_type(
serde::de::Unexpected::UnitVariant, serde::de::Unexpected::UnitVariant,
&"tuple variant", &"tuple variant",
)) )),
} }
} }
fn struct_variant<V>( fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
self, _fields: &'static [&'static str], visitor: V where
) -> Result<V::Value> V: serde::de::Visitor<'de>,
where V: serde::de::Visitor<'de>
{ {
match self.value { match self.value {
Some(value) => serde::Deserializer::deserialize_map( Some(value) => serde::Deserializer::deserialize_map(Deserializer { value }, visitor),
Deserializer { value }, visitor
),
None => Err(serde::de::Error::invalid_type( None => Err(serde::de::Error::invalid_type(
serde::de::Unexpected::UnitVariant, serde::de::Unexpected::UnitVariant,
&"struct variant", &"struct variant",
)) )),
} }
} }
} }
@ -285,23 +302,26 @@ mod tests {
int: 1, int: 1,
seq: vec!["a".to_owned(), "b".to_owned()], seq: vec!["a".to_owned(), "b".to_owned()],
map: vec![(1, 2), (4, 1)].into_iter().collect(), map: vec![(1, 2), (4, 1)].into_iter().collect(),
empty: vec![] empty: vec![],
}; };
println!("{:?}", expected); println!("{:?}", expected);
let lua = Lua::new(); let lua = Lua::new();
lua.context(|lua| { let value = lua
let value = lua.load(r#" .load(
r#"
a = {} a = {}
a.int = 1 a.int = 1
a.seq = {"a", "b"} a.seq = {"a", "b"}
a.map = {2, [4]=1} a.map = {2, [4]=1}
a.empty = {} a.empty = {}
return a return a
"#).eval().unwrap(); "#,
let got = from_value(value).unwrap(); )
assert_eq!(expected, got); .eval()
}); .unwrap();
let got = from_value(value).unwrap();
assert_eq!(expected, got);
} }
#[test] #[test]
@ -310,25 +330,31 @@ mod tests {
struct Rgb(u8, u8, u8); struct Rgb(u8, u8, u8);
let lua = Lua::new(); let lua = Lua::new();
lua.context(|lua| { let expected = Rgb(1, 2, 3);
let expected = Rgb(1, 2, 3); let value = lua
let value = lua.load( .load(
r#" r#"
a = {1, 2, 3} a = {1, 2, 3}
return a return a
"#).eval().unwrap(); "#,
let got = from_value(value).unwrap(); )
assert_eq!(expected, got); .eval()
.unwrap();
let got = from_value(value).unwrap();
assert_eq!(expected, got);
let expected = (1, 2, 3); let expected = (1, 2, 3);
let value = lua.load( let value = lua
.load(
r#" r#"
a = {1, 2, 3} a = {1, 2, 3}
return a return a
"#).eval().unwrap(); "#,
let got = from_value(value).unwrap(); )
assert_eq!(expected, got); .eval()
}); .unwrap();
let got = from_value(value).unwrap();
assert_eq!(expected, got);
} }
#[test] #[test]
@ -342,46 +368,59 @@ mod tests {
} }
let lua = Lua::new(); let lua = Lua::new();
lua.context(|lua| {
let expected = E::Unit; let expected = E::Unit;
let value = lua.load( let value = lua
r#" .load(
r#"
return "Unit" return "Unit"
"#).eval().unwrap(); "#,
)
.eval()
.unwrap();
let got = from_value(value).unwrap(); let got = from_value(value).unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
let expected = E::Newtype(1); let expected = E::Newtype(1);
let value = lua.load( let value = lua
r#" .load(
r#"
a = {} a = {}
a["Newtype"] = 1 a["Newtype"] = 1
return a return a
"#).eval().unwrap(); "#,
)
.eval()
.unwrap();
let got = from_value(value).unwrap(); let got = from_value(value).unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
let expected = E::Tuple(1, 2); let expected = E::Tuple(1, 2);
let value = lua.load( let value = lua
r#" .load(
r#"
a = {} a = {}
a["Tuple"] = {1, 2} a["Tuple"] = {1, 2}
return a return a
"#).eval().unwrap(); "#,
)
.eval()
.unwrap();
let got = from_value(value).unwrap(); let got = from_value(value).unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
let expected = E::Struct { a: 1 }; let expected = E::Struct { a: 1 };
let value = lua.load( let value = lua
r#" .load(
r#"
a = {} a = {}
a["Struct"] = {} a["Struct"] = {}
a["Struct"]["a"] = 1 a["Struct"]["a"] = 1
return a return a
"#).eval().unwrap(); "#,
)
.eval()
.unwrap();
let got = from_value(value).unwrap(); let got = from_value(value).unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
});
} }
} }

View File

@ -20,20 +20,18 @@
//! } //! }
//! //!
//! let lua = mlua::Lua::new(); //! let lua = mlua::Lua::new();
//! lua.context(|lua| { //! let foo = Foo {
//! let foo = Foo { //! bar: 42,
//! bar: 42, //! baz: vec![String::from("fizz"), String::from("buzz")],
//! baz: vec![String::from("fizz"), String::from("buzz")], //! };
//! };
//! //!
//! let value = mlua_serde::to_value(lua, &foo).unwrap(); //! let value = mlua_serde::to_value(&lua, &foo).unwrap();
//! lua.globals().set("value", value).unwrap(); //! lua.globals().set("value", value).unwrap();
//! lua.load( //! lua.load(
//! r#" //! r#"
//! assert(value["bar"] == 42) //! assert(value["bar"] == 42)
//! assert(value["baz"][2] == "buzz") //! assert(value["baz"][2] == "buzz")
//! "#).exec().unwrap(); //! "#).exec().unwrap();
//! });
//! } //! }
//! ``` //! ```

View File

@ -1,10 +1,9 @@
use serde; use serde;
use mlua::{Lua, Value, Table, String as LuaString}; use mlua::{Lua, String as LuaString, Table, Value};
use to_value;
use error::{Error, Result}; use error::{Error, Result};
use to_value;
pub struct Serializer<'lua> { pub struct Serializer<'lua> {
pub lua: &'lua Lua, pub lua: &'lua Lua,
@ -14,12 +13,12 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
type Ok = Value<'lua>; type Ok = Value<'lua>;
type Error = Error; type Error = Error;
type SerializeSeq = SerializeVec<'lua>; type SerializeSeq = SerializeVec<'lua>;
type SerializeTuple = SerializeVec<'lua>; type SerializeTuple = SerializeVec<'lua>;
type SerializeTupleStruct = SerializeVec<'lua>; type SerializeTupleStruct = SerializeVec<'lua>;
type SerializeTupleVariant = SerializeTupleVariant<'lua>; type SerializeTupleVariant = SerializeTupleVariant<'lua>;
type SerializeMap = SerializeMap<'lua>; type SerializeMap = SerializeMap<'lua>;
type SerializeStruct = SerializeMap<'lua>; type SerializeStruct = SerializeMap<'lua>;
type SerializeStructVariant = SerializeStructVariant<'lua>; type SerializeStructVariant = SerializeStructVariant<'lua>;
#[inline] #[inline]
@ -91,7 +90,9 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
#[inline] #[inline]
fn serialize_bytes(self, value: &[u8]) -> Result<Value<'lua>> { fn serialize_bytes(self, value: &[u8]) -> Result<Value<'lua>> {
Ok(Value::Table(self.lua.create_sequence_from(value.iter().cloned())?)) Ok(Value::Table(
self.lua.create_sequence_from(value.iter().cloned())?,
))
} }
#[inline] #[inline]
@ -106,25 +107,31 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
#[inline] #[inline]
fn serialize_unit_variant( fn serialize_unit_variant(
self, _name: &'static str, _variant_index: u32, variant: &'static str self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Value<'lua>> { ) -> Result<Value<'lua>> {
self.serialize_str(variant) self.serialize_str(variant)
} }
#[inline] #[inline]
fn serialize_newtype_struct<T>( fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Value<'lua>>
self, _name: &'static str, value: &T where
) -> Result<Value<'lua>> T: ?Sized + serde::Serialize,
where T: ?Sized + serde::Serialize,
{ {
value.serialize(self) value.serialize(self)
} }
fn serialize_newtype_variant<T>( fn serialize_newtype_variant<T>(
self, _name: &'static str, _variant_index: u32, self,
variant: &'static str, value: &T, _name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Value<'lua>> ) -> Result<Value<'lua>>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
let table = self.lua.create_table()?; let table = self.lua.create_table()?;
let variant = self.lua.create_string(variant)?; let variant = self.lua.create_string(variant)?;
@ -140,7 +147,8 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
#[inline] #[inline]
fn serialize_some<T>(self, value: &T) -> Result<Value<'lua>> fn serialize_some<T>(self, value: &T) -> Result<Value<'lua>>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
value.serialize(self) value.serialize(self)
} }
@ -159,14 +167,19 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
} }
fn serialize_tuple_struct( fn serialize_tuple_struct(
self, _name: &'static str, len: usize, self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> { ) -> Result<Self::SerializeTupleStruct> {
self.serialize_seq(Some(len)) self.serialize_seq(Some(len))
} }
fn serialize_tuple_variant( fn serialize_tuple_variant(
self, _name: &'static str, _variant_index: u32, self,
variant: &'static str, _len: usize, _name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> { ) -> Result<Self::SerializeTupleVariant> {
let name = self.lua.create_string(variant)?; let name = self.lua.create_string(variant)?;
let table = self.lua.create_table()?; let table = self.lua.create_table()?;
@ -174,7 +187,7 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
lua: self.lua, lua: self.lua,
idx: 1, idx: 1,
name, name,
table table,
}) })
} }
@ -192,8 +205,11 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
} }
fn serialize_struct_variant( fn serialize_struct_variant(
self, _name: &'static str, _variant_index: u32, self,
variant: &'static str, _len: usize, _name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> { ) -> Result<Self::SerializeStructVariant> {
let name = self.lua.create_string(variant)?; let name = self.lua.create_string(variant)?;
let table = self.lua.create_table()?; let table = self.lua.create_table()?;
@ -203,10 +219,8 @@ impl<'lua> serde::Serializer for Serializer<'lua> {
table, table,
}) })
} }
} }
pub struct SerializeVec<'lua> { pub struct SerializeVec<'lua> {
lua: &'lua Lua, lua: &'lua Lua,
table: Table<'lua>, table: Table<'lua>,
@ -218,7 +232,8 @@ impl<'lua> serde::ser::SerializeSeq for SerializeVec<'lua> {
type Error = Error; type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()> fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
self.table.set(self.idx, to_value(self.lua, value)?)?; self.table.set(self.idx, to_value(self.lua, value)?)?;
self.idx += 1; self.idx += 1;
@ -235,7 +250,8 @@ impl<'lua> serde::ser::SerializeTuple for SerializeVec<'lua> {
type Error = Error; type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()> fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
serde::ser::SerializeSeq::serialize_element(self, value) serde::ser::SerializeSeq::serialize_element(self, value)
} }
@ -250,7 +266,8 @@ impl<'lua> serde::ser::SerializeTupleStruct for SerializeVec<'lua> {
type Error = Error; type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()> fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
serde::ser::SerializeSeq::serialize_element(self, value) serde::ser::SerializeSeq::serialize_element(self, value)
} }
@ -260,7 +277,6 @@ impl<'lua> serde::ser::SerializeTupleStruct for SerializeVec<'lua> {
} }
} }
pub struct SerializeTupleVariant<'lua> { pub struct SerializeTupleVariant<'lua> {
lua: &'lua Lua, lua: &'lua Lua,
name: LuaString<'lua>, name: LuaString<'lua>,
@ -273,7 +289,8 @@ impl<'lua> serde::ser::SerializeTupleVariant for SerializeTupleVariant<'lua> {
type Error = Error; type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()> fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
self.table.set(self.idx, to_value(self.lua, value)?)?; self.table.set(self.idx, to_value(self.lua, value)?)?;
self.idx += 1; self.idx += 1;
@ -287,11 +304,10 @@ impl<'lua> serde::ser::SerializeTupleVariant for SerializeTupleVariant<'lua> {
} }
} }
pub struct SerializeMap<'lua> { pub struct SerializeMap<'lua> {
lua: &'lua Lua, lua: &'lua Lua,
table: Table<'lua>, table: Table<'lua>,
next_key: Option<Value<'lua>> next_key: Option<Value<'lua>>,
} }
impl<'lua> serde::ser::SerializeMap for SerializeMap<'lua> { impl<'lua> serde::ser::SerializeMap for SerializeMap<'lua> {
@ -299,14 +315,16 @@ impl<'lua> serde::ser::SerializeMap for SerializeMap<'lua> {
type Error = Error; type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()> fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
self.next_key = Some(to_value(self.lua, key)?); self.next_key = Some(to_value(self.lua, key)?);
Ok(()) Ok(())
} }
fn serialize_value<T>(&mut self, value: &T) -> Result<()> fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
let key = self.next_key.take(); let key = self.next_key.take();
// Panic because this indicates a bug in the program rather than an // Panic because this indicates a bug in the program rather than an
@ -326,7 +344,8 @@ impl<'lua> serde::ser::SerializeStruct for SerializeMap<'lua> {
type Error = Error; type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
serde::ser::SerializeMap::serialize_key(self, key)?; serde::ser::SerializeMap::serialize_key(self, key)?;
serde::ser::SerializeMap::serialize_value(self, value) serde::ser::SerializeMap::serialize_value(self, value)
@ -337,7 +356,6 @@ impl<'lua> serde::ser::SerializeStruct for SerializeMap<'lua> {
} }
} }
pub struct SerializeStructVariant<'lua> { pub struct SerializeStructVariant<'lua> {
lua: &'lua Lua, lua: &'lua Lua,
name: LuaString<'lua>, name: LuaString<'lua>,
@ -349,10 +367,10 @@ impl<'lua> serde::ser::SerializeStructVariant for SerializeStructVariant<'lua> {
type Error = Error; type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where T: ?Sized + serde::Serialize, where
T: ?Sized + serde::Serialize,
{ {
self.table self.table.set(key, to_value(self.lua, value)?)?;
.set(key, to_value(self.lua, value)?)?;
Ok(()) Ok(())
} }
@ -365,8 +383,8 @@ impl<'lua> serde::ser::SerializeStructVariant for SerializeStructVariant<'lua> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use mlua::Lua;
use super::*; use super::*;
use mlua::Lua;
#[test] #[test]
fn test_struct() { fn test_struct() {
@ -376,19 +394,23 @@ mod tests {
seq: Vec<&'static str>, seq: Vec<&'static str>,
} }
let test = Test { int: 1, seq: vec!["a", "b"] }; let test = Test {
int: 1,
seq: vec!["a", "b"],
};
let lua = Lua::new(); let lua = Lua::new();
lua.context(|lua| { let value = to_value(&lua, &test).unwrap();
let value = to_value(lua, &test).unwrap(); lua.globals().set("value", value).unwrap();
lua.globals().set("value", value).unwrap(); lua.load(
lua.load( r#"
r#"
assert(value["int"] == 1) assert(value["int"] == 1)
assert(value["seq"][1] == "a") assert(value["seq"][1] == "a")
assert(value["seq"][2] == "b") assert(value["seq"][2] == "b")
"#).exec() "#,
}).unwrap() )
.exec()
.unwrap()
} }
#[test] #[test]
@ -398,40 +420,54 @@ mod tests {
Unit, Unit,
Newtype(u32), Newtype(u32),
Tuple(u32, u32), Tuple(u32, u32),
Struct { a: u32}, Struct { a: u32 },
} }
let lua = Lua::new(); let lua = Lua::new();
lua.context(|lua| { let u = E::Unit;
let u = E::Unit; let value = to_value(&lua, &u).unwrap();
let value = to_value(lua, &u).unwrap(); lua.globals().set("value", value).unwrap();
lua.globals().set("value", value).unwrap(); lua.load(
lua.load(r#" r#"
assert(value == "Unit") assert(value == "Unit")
"#).exec().unwrap(); "#,
)
.exec()
.unwrap();
let n = E::Newtype(1); let n = E::Newtype(1);
let value = to_value(lua, &n).unwrap(); let value = to_value(&lua, &n).unwrap();
lua.globals().set("value", value).unwrap(); lua.globals().set("value", value).unwrap();
lua.load(r#" lua.load(
r#"
assert(value["Newtype"] == 1) assert(value["Newtype"] == 1)
"#).exec().unwrap(); "#,
)
.exec()
.unwrap();
let t = E::Tuple(1, 2); let t = E::Tuple(1, 2);
let value = to_value(lua, &t).unwrap(); let value = to_value(&lua, &t).unwrap();
lua.globals().set("value", value).unwrap(); lua.globals().set("value", value).unwrap();
lua.load(r#" lua.load(
r#"
assert(value["Tuple"][1] == 1) assert(value["Tuple"][1] == 1)
assert(value["Tuple"][2] == 2) assert(value["Tuple"][2] == 2)
"#).exec().unwrap(); "#,
)
.exec()
.unwrap();
let s = E::Struct { a: 1 }; let s = E::Struct { a: 1 };
let value = to_value(lua, &s).unwrap(); let value = to_value(&lua, &s).unwrap();
lua.globals().set("value", value).unwrap(); lua.globals().set("value", value).unwrap();
lua.load(r#" lua.load(
r#"
assert(value["Struct"]["a"] == 1) assert(value["Struct"]["a"] == 1)
"#).exec() "#,
}).unwrap(); )
.exec()
.unwrap();
} }
} }