Difficulty deserializing Lua functions with mlua
tickox opened this issue · 6 comments
Hello,
I am new to Rust and trying to use mlua. I am having difficulty deserializing Lua functions in Rust. What steps are necessary to make this work correctly?
In case of an error due to extra or missing fields, is it possible to identify which Lua line is causing the problem to facilitate debugging ?
Here is an example code:
#[derive(Deserialize)]
struct Test<'lua> {
name: String,
callback: Option<Function<'lua>>,
}
fn main() -> Result<()> {
let lua = Lua::new();
let lua_file = r#"
{
"name"= "test",
"callback"= function(table)
print("ok")
end
}
"#;
let test: Test = lua.from_value(lua.load(lua_file).eval()?)?;
Ok(())
}
Thank you for your help!
Functions does not support serializations/deserializations through serde.
Would be better to implement FromLua
for the Test
struct.
sort of:
impl<'lua> FromLua<'lua> for Test<'lua> {
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
let table = value.as_table().unwrap();
Ok(Test {
name: table.get("name")?,
callback: table.get("callback")?
})
}
}
Ok thanks you
The solution above seems not to work with lifetime issues. Also trying to implement with extensive lifetime annotations does not help :-(
use mlua::{FromLua, Function, Lua, LuaSerdeExt, Result, Value};
use serde_derive::Deserialize;
#[derive(Deserialize)]
struct Test<'lua> {
name: String,
callback: Option<Function<'lua>>,
}
impl<'lua> FromLua<'lua> for Test<'lua> {
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
let table = value.as_table().unwrap();
let name: String = table.get("name")?;
let callback: Option<Function<'lua>> = table.get("callback")?;
Ok(Test { name, callback })
}
}
fn main() -> Result<()> {
let lua = Lua::new();
let lua_file = r#" {
name= "test",
callback= function(table)
print("ok")
end
}
"#;
let test: Test = lua.from_value(lua.load(lua_file).eval()?)?;
Ok(())
}
@PatWie
try this:
use mlua::{FromLua, Function, Lua, Result, Table, Value};
#[derive(Debug)]
struct Test<'lua> {
name: String,
callback: Option<Function<'lua>>,
}
impl<'lua> FromLua<'lua> for Test<'lua> {
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
let table: Table = lua.unpack(value)?;
let name = table.get("name")?;
let callback = table.get("callback")?;
Ok(Test { name, callback })
}
}
fn main() -> Result<()> {
let lua = Lua::new();
let lua_file = r#" {
name= "test",
callback= function(table)
print("ok")
end
}
"#;
let test: Test = lua.load(lua_file).eval()?;
println!("{test:?}");
Ok(())
}
I just realised that lifetime in Value::as_table
is wrong because they point to self
lifetime instead of 'lua
(Table<'self>
but should be Table<'lua>
)
Also you can try v0.10-beta that does not have any lifetimes.
Holy moly,
that version is awesome! This is unblocking me in my own language-server project with LLMs, Lua, Rust. Thanks a lot!!!