mlua-rs / rlua

High level Lua bindings to Rust
Other
1.73k stars 115 forks source link

Missing API #249

Closed Yuri6037 closed 9 months ago

Yuri6037 commented 2 years ago

I have a method named rgba on a struct which I'd like to map to a UserData. The return type of the method is Option<(u8, u8, u8, u8)>. Unfortunately rule has no built-in ToLuaMulti implemented for an optional tuple. The expected lua result is nil for None and 4 integer returns if Some.

Can the API be extended to allow sending optional tuples to lua?

jugglerchris commented 2 years ago

Hi, I think implementing ToLuaMulti like that could cause confusion, as there's already a ToLua implementation for Option<T>. However it's not too hard to use MultiValue to do what you want - see the closure passed to create_function below as a wrapper if your function can't return MultiValue directly:

    fn test1(x: bool) -> Option<(u8, u8, u8, u8)> {
        if x {
            Some((1,2,3,4))
        } else {
            None
        }
    }
    Lua::new().context(|lua| {
        let globals = lua.globals();
        let f = lua.create_function(move |lua, x: bool| {
            match test1(x) {
                Some(v) => v.to_lua_multi(lua),
                None => Value::Nil.to_lua_multi(lua),
            }
        }).unwrap();
        globals.set("f", f).unwrap();
        lua.load(
            r#"
                local t = table.pack(f(false))
                assert(t.n == 1)
                assert(t[1] == nil)

                local u = table.pack(f(true))
                assert(u.n == 4)
                assert(u[1] == 1)
                assert(u[2] == 2)
                assert(u[3] == 3)
                assert(u[4] == 4)
            "#,
        )
        .exec()
        .unwrap();
    });