aboutsummaryrefslogtreecommitdiff
path: root/src/lua/serde/ser.rs
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2022-08-13 03:56:55 +0200
committerMartin Fischer <martin@push-f.com>2022-08-14 00:33:23 +0200
commit36e98c1b135f07ef9a5eec046b8f0fd6d93534d4 (patch)
treeda9c93ceb0e147695e1992c4d1678964af3be4bf /src/lua/serde/ser.rs
parentdc20e1df60c1e4e81d1e16e8f177a1c6956966b7 (diff)
add gitpad.decode_toml lua method
We are vendoring the rlua_serde crate because it currently depends on rlua 0.17, which is outdated and my attempts to contact the crate author were bounced by Yandex for somehow looking like spam.
Diffstat (limited to 'src/lua/serde/ser.rs')
-rw-r--r--src/lua/serde/ser.rs481
1 files changed, 481 insertions, 0 deletions
diff --git a/src/lua/serde/ser.rs b/src/lua/serde/ser.rs
new file mode 100644
index 0000000..8af978a
--- /dev/null
+++ b/src/lua/serde/ser.rs
@@ -0,0 +1,481 @@
+// vendored from https://github.com/zrkn/rlua_serde because it dependend on an outdated rlua version
+// Copyright (c) 2018 zrkn <zrkn@email.su>, licensed under the MIT License
+
+use serde;
+
+use rlua::{Context, String as LuaString, Table, Value};
+
+use super::error::{Error, Result};
+use super::to_value;
+
+pub struct Serializer<'lua> {
+ pub lua: Context<'lua>,
+}
+
+impl<'lua> serde::Serializer for Serializer<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ type SerializeSeq = SerializeVec<'lua>;
+ type SerializeTuple = SerializeVec<'lua>;
+ type SerializeTupleStruct = SerializeVec<'lua>;
+ type SerializeTupleVariant = SerializeTupleVariant<'lua>;
+ type SerializeMap = SerializeMap<'lua>;
+ type SerializeStruct = SerializeMap<'lua>;
+ type SerializeStructVariant = SerializeStructVariant<'lua>;
+
+ #[inline]
+ fn serialize_bool(self, value: bool) -> Result<Value<'lua>> {
+ Ok(Value::Boolean(value))
+ }
+
+ #[inline]
+ fn serialize_i8(self, value: i8) -> Result<Value<'lua>> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i16(self, value: i16) -> Result<Value<'lua>> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i32(self, value: i32) -> Result<Value<'lua>> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i64(self, value: i64) -> Result<Value<'lua>> {
+ Ok(Value::Integer(value))
+ }
+
+ #[inline]
+ fn serialize_u8(self, value: u8) -> Result<Value<'lua>> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u16(self, value: u16) -> Result<Value<'lua>> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u32(self, value: u32) -> Result<Value<'lua>> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u64(self, value: u64) -> Result<Value<'lua>> {
+ self.serialize_i64(value as i64)
+ }
+
+ #[inline]
+ fn serialize_f32(self, value: f32) -> Result<Value<'lua>> {
+ self.serialize_f64(f64::from(value))
+ }
+
+ #[inline]
+ fn serialize_f64(self, value: f64) -> Result<Value<'lua>> {
+ Ok(Value::Number(value))
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<Value<'lua>> {
+ let mut s = String::new();
+ s.push(value);
+ self.serialize_str(&s)
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<Value<'lua>> {
+ Ok(Value::String(self.lua.create_string(value)?))
+ }
+
+ #[inline]
+ fn serialize_bytes(self, value: &[u8]) -> Result<Value<'lua>> {
+ Ok(Value::Table(
+ self.lua.create_sequence_from(value.iter().cloned())?,
+ ))
+ }
+
+ #[inline]
+ fn serialize_unit(self) -> Result<Value<'lua>> {
+ Ok(Value::Nil)
+ }
+
+ #[inline]
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Value<'lua>> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Value<'lua>> {
+ self.serialize_str(variant)
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Value<'lua>>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Value<'lua>>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ let table = self.lua.create_table()?;
+ let variant = self.lua.create_string(variant)?;
+ let value = to_value(self.lua, value)?;
+ table.set(variant, value)?;
+ Ok(Value::Table(table))
+ }
+
+ #[inline]
+ fn serialize_none(self) -> Result<Value<'lua>> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_some<T>(self, value: &T) -> Result<Value<'lua>>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+ let table = self.lua.create_table()?;
+ Ok(SerializeVec {
+ lua: self.lua,
+ idx: 1,
+ table,
+ })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ let name = self.lua.create_string(variant)?;
+ let table = self.lua.create_table()?;
+ Ok(SerializeTupleVariant {
+ lua: self.lua,
+ idx: 1,
+ name,
+ table,
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ let table = self.lua.create_table()?;
+ Ok(SerializeMap {
+ lua: self.lua,
+ next_key: None,
+ table,
+ })
+ }
+
+ fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+ self.serialize_map(Some(len))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ let name = self.lua.create_string(variant)?;
+ let table = self.lua.create_table()?;
+ Ok(SerializeStructVariant {
+ lua: self.lua,
+ name,
+ table,
+ })
+ }
+}
+
+pub struct SerializeVec<'lua> {
+ lua: Context<'lua>,
+ table: Table<'lua>,
+ idx: u64,
+}
+
+impl<'lua> serde::ser::SerializeSeq for SerializeVec<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ self.table.set(self.idx, to_value(self.lua, value)?)?;
+ self.idx += 1;
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value<'lua>> {
+ Ok(Value::Table(self.table))
+ }
+}
+
+impl<'lua> serde::ser::SerializeTuple for SerializeVec<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value<'lua>> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+impl<'lua> serde::ser::SerializeTupleStruct for SerializeVec<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value<'lua>> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+pub struct SerializeTupleVariant<'lua> {
+ lua: Context<'lua>,
+ name: LuaString<'lua>,
+ table: Table<'lua>,
+ idx: u64,
+}
+
+impl<'lua> serde::ser::SerializeTupleVariant for SerializeTupleVariant<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ self.table.set(self.idx, to_value(self.lua, value)?)?;
+ self.idx += 1;
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value<'lua>> {
+ let table = self.lua.create_table()?;
+ table.set(self.name, self.table)?;
+ Ok(Value::Table(table))
+ }
+}
+
+pub struct SerializeMap<'lua> {
+ lua: Context<'lua>,
+ table: Table<'lua>,
+ next_key: Option<Value<'lua>>,
+}
+
+impl<'lua> serde::ser::SerializeMap for SerializeMap<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ self.next_key = Some(to_value(self.lua, key)?);
+ Ok(())
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ let key = self.next_key.take();
+ // Panic because this indicates a bug in the program rather than an
+ // expected failure.
+ let key = key.expect("serialize_value called before serialize_key");
+ self.table.set(key, to_value(self.lua, value)?)?;
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value<'lua>> {
+ Ok(Value::Table(self.table))
+ }
+}
+
+impl<'lua> serde::ser::SerializeStruct for SerializeMap<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ serde::ser::SerializeMap::serialize_key(self, key)?;
+ serde::ser::SerializeMap::serialize_value(self, value)
+ }
+
+ fn end(self) -> Result<Value<'lua>> {
+ serde::ser::SerializeMap::end(self)
+ }
+}
+
+pub struct SerializeStructVariant<'lua> {
+ lua: Context<'lua>,
+ name: LuaString<'lua>,
+ table: Table<'lua>,
+}
+
+impl<'lua> serde::ser::SerializeStructVariant for SerializeStructVariant<'lua> {
+ type Ok = Value<'lua>;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + serde::Serialize,
+ {
+ self.table.set(key, to_value(self.lua, value)?)?;
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value<'lua>> {
+ let table = self.lua.create_table()?;
+ table.set(self.name, self.table)?;
+ Ok(Value::Table(table))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use rlua::Lua;
+ use serde::Serialize;
+
+ #[test]
+ fn test_struct() {
+ #[derive(Serialize)]
+ struct Test {
+ int: u32,
+ seq: Vec<&'static str>,
+ }
+
+ let test = Test {
+ int: 1,
+ seq: vec!["a", "b"],
+ };
+
+ let lua = Lua::new();
+ lua.context(|lua| {
+ let value = to_value(lua, &test).unwrap();
+ lua.globals().set("value", value).unwrap();
+ lua.load(
+ r#"
+ assert(value["int"] == 1)
+ assert(value["seq"][1] == "a")
+ assert(value["seq"][2] == "b")
+ "#,
+ )
+ .exec()
+ })
+ .unwrap()
+ }
+
+ #[test]
+ fn test_num() {
+ #[derive(Serialize)]
+ enum E {
+ Unit,
+ Newtype(u32),
+ Tuple(u32, u32),
+ Struct { a: u32 },
+ }
+
+ let lua = Lua::new();
+
+ lua.context(|lua| {
+ let u = E::Unit;
+ let value = to_value(lua, &u).unwrap();
+ lua.globals().set("value", value).unwrap();
+ lua.load(
+ r#"
+ assert(value == "Unit")
+ "#,
+ )
+ .exec()
+ .unwrap();
+
+ let n = E::Newtype(1);
+ let value = to_value(lua, &n).unwrap();
+ lua.globals().set("value", value).unwrap();
+ lua.load(
+ r#"
+ assert(value["Newtype"] == 1)
+ "#,
+ )
+ .exec()
+ .unwrap();
+
+ let t = E::Tuple(1, 2);
+ let value = to_value(lua, &t).unwrap();
+ lua.globals().set("value", value).unwrap();
+ lua.load(
+ r#"
+ assert(value["Tuple"][1] == 1)
+ assert(value["Tuple"][2] == 2)
+ "#,
+ )
+ .exec()
+ .unwrap();
+
+ let s = E::Struct { a: 1 };
+ let value = to_value(lua, &s).unwrap();
+ lua.globals().set("value", value).unwrap();
+ lua.load(
+ r#"
+ assert(value["Struct"]["a"] == 1)
+ "#,
+ )
+ .exec()
+ })
+ .unwrap();
+ }
+}