Skip to content

Missing impl IntoLuaMulti for Either<L: IntoLuaMulti, R: IntoLuaMulti> #657

@LunarLambda

Description

@LunarLambda

I wanted to use create_function with this function:

fn read(lua: &Lua, filename: PathBuf) -> LuaResult<Either<String, (LuaValue, String, Option<i32>)>> {
    match std::fs::read_to_string(&filename) {
        Ok(string) => Ok(Either::Left(string)),
        Err(error) => Ok(Either::Right((
            Nil, format!("{}: {error}", filename.display()), error.raw_os_error()
        )))
    }
}

String, LuaValue (mlua::Value), and Option<i32> all implement IntoLua, so the tuple (LuaValue, String, Option<i32>) implements IntoLuaMulti. Additionally String implements IntoLuaMulti via impl<T: IntoLua> IntoLuaMulti for T

However, unfortunately Either only has impl<L: IntoLua, R: IntoLua> IntoLua for Either<L, R>, not the equivalent using IntoLuaMulti.

More unfortunately, the blanket impl IntoLuaMulti for T where T: IntoLua prevents Either from implementing both traits.
There is a IntoLuaMulti impl for Result<T, E> but it too uses T: IntoLua, E: IntoLua.

I'm not sure I can propose a concrete fix, but the current set of IntoLua/IntoLuaMulti impls makes it exceedingly to difficult to do multi-valued error returns in the style of io.open (which returns nil, string, number, with the last value being the errno/error code value)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions