How can I pass in a global table, allow user to modify it via script and then read the updated values from Rust? #370
-
Hi, I'm trying to use mlua to allow users of my app to configure it with lua scripts. I'd like to pass in a global akin to something like My first attempt is something like this: let lua = Lua::new();
let globals = lua.globals();
let config = Config {
a: 0,
b: String::new(),
};
globals.set("config", config).unwrap();
lua.load(
r#"
config.a = 4
config.b = "hi from lua"
"#,
)
.exec()
.unwrap();
let config_from_lua: Config = globals.get("config").unwrap();
println!("{}", config_from_lua.b); And config looks like this: #[derive(Serialize, Deserialize, Clone)]
pub struct Config {
a: i32,
b: String,
}
impl UserData for Config {}
impl<'lua> FromLua<'lua> for Config {
fn from_lua(
value: mlua::prelude::LuaValue<'lua>,
lua: &'lua Lua,
) -> mlua::prelude::LuaResult<Self> {
match value {
mlua::Value::UserData(ud) => Ok(ud.take::<Self>()?),
_ => unreachable!(),
}
}
} When I try to run this code I get a runtime error at the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
To get access to the #[derive(Serialize, Deserialize, Clone, mlua::FromLua)]
pub struct Config {
a: i32,
b: String,
}
impl mlua::UserData for Config {
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
fields.add_field_method_get("a", |_, this| Ok(this.a));
fields.add_field_method_get("b", |_, this| Ok(this.b.clone()));
fields.add_field_method_set("a", |_, this, a| {
this.a = a;
Ok(())
});
fields.add_field_method_set("b", |_, this, b| {
this.b = b;
Ok(())
});
}
} Also you don't need to manually implement |
Beta Was this translation helpful? Give feedback.
To get access to the
Config
fields, you need to implement accessors (yet; future mlua versions will have a derive macro for this)For your case the code example would be: