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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions