mlua icon indicating copy to clipboard operation
mlua copied to clipboard

Reinstate str helpers under better name

Open MightyPork opened this issue 5 months ago • 2 comments

Hi, first thanks for maintaining the library.

Regarding a3302af

this just made some work with Value a lot more cumbersome. Calling the Lua string type String is also confusing but that is now part of the API and has to stay. I just rename all the Lua types on import.

I solved the removal of these helpers for now by adding a custom extension trait

pub trait LuaValueExt {
    fn as_str_opt(&self) -> Option<mlua::BorrowedStr<'_>>;
}

impl LuaValueExt for LuaValue {
    fn as_str_opt(&self) -> Option<mlua::BorrowedStr<'_>> {
        self.as_string().and_then(|s| s.to_str().ok())
    }
}

however this feels like something so obvious, it deserves to be included.

I also got tripped by as_f64 not doing a cast if the value is Integer, so I now have custom helpers for that as well, such as

    fn to_f64(&self) -> Result<f64, ConvertError> {
        match &self.0 {
            LuaValue::Nil => Ok(0.0),
            LuaValue::Boolean(v) => Ok(if *v { 1.0 } else { 0.0 }),
            LuaValue::Integer(v) => Ok(*v as f64),
            LuaValue::Number(v) => Ok(*v),
            LuaValue::String(v) => v
                .to_string_lossy()
                .parse::<f64>()
                .map_err(|e| ConvertError::Other(e.to_string().into())),
            LuaValue::LightUserData(_)
            | LuaValue::Table(_)
            | LuaValue::Function(_)
            | LuaValue::Thread(_)
            | LuaValue::UserData(_)
            | LuaValue::Error(_)
            | LuaValue::Other(_) => Err(ConvertError::TypeMismatch),
        }
    }

MightyPork avatar Jul 29 '25 09:07 MightyPork

Calling the Lua string type String is also confusing but that is now part of the API and has to stay.

I agree. mlua inherited it from rlua and I usually use LuaString alias or mlua::String in my projects.

I also got tripped by as_f64 not doing a cast if the value is Integer, so I now have custom helpers for that as well, such as

Have you tried Lua::coerce_number instead?

The Lua conversion behaviour is documented here and here

The LuaValue::Nil => Ok(0.0) and LuaValue::Boolean(v) => Ok(if *v { 1.0 } else { 0.0 }) seems quite specific.

khvzak avatar Jul 29 '25 22:07 khvzak

The LuaValue::Nil => Ok(0.0) and LuaValue::Boolean(v) => Ok(if *v { 1.0 } else { 0.0 }) seems quite specific.

yeah I agree, these were probably not needed for the actual use case. I tried to cover all situations that made at least some sense, so that's where this came from. The conversion trait is a lot more complex than this, there is also to_i64, to_u64, to_bool and to_string, and then also conversions to other integer widths. We are converting lua value to something that can be written to different kinds of Modbus registers.

MightyPork avatar Jul 30 '25 06:07 MightyPork