diff options
author | Alex Orlenko <zxteam@protonmail.com> | 2022-05-30 19:26:12 +0100 |
---|---|---|
committer | Alex Orlenko <zxteam@protonmail.com> | 2022-05-30 19:26:12 +0100 |
commit | a05a58b2588377bcb214f0ef28c1342b3b67dc17 (patch) | |
tree | 26bd7329d4c7c3450a7eca0552c42d2303c366be | |
parent | 3766cee4ddd70058121b3eb0a5261e4c2557ea0e (diff) | |
download | mlua-a05a58b2588377bcb214f0ef28c1342b3b67dc17.zip |
Update integer/number coercion logic
-rw-r--r-- | src/conversion.rs | 30 | ||||
-rw-r--r-- | src/lua.rs | 28 | ||||
-rw-r--r-- | tests/tests.rs | 7 |
3 files changed, 44 insertions, 21 deletions
diff --git a/src/conversion.rs b/src/conversion.rs index 6682959..59717f0 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -376,20 +376,24 @@ macro_rules! lua_convert_int { #[inline] fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> { let ty = value.type_name(); - (if let Value::Integer(i) = value { - cast(i) - } else if let Some(i) = lua.coerce_integer(value.clone())? { - cast(i) - } else { - cast(lua.coerce_number(value)?.ok_or_else(|| { - Error::FromLuaConversionError { - from: ty, - to: stringify!($x), - message: Some( - "expected number or string coercible to number".to_string(), - ), + (match value { + Value::Integer(i) => cast(i), + Value::Number(n) => cast(n), + _ => { + if let Some(i) = lua.coerce_integer(value.clone())? { + cast(i) + } else { + cast(lua.coerce_number(value)?.ok_or_else(|| { + Error::FromLuaConversionError { + from: ty, + to: stringify!($x), + message: Some( + "expected number or string coercible to number".to_string(), + ), + } + })?) } - })?) + } }) .ok_or_else(|| Error::FromLuaConversionError { from: ty, @@ -2304,15 +2304,29 @@ impl Lua { ud } + #[cfg(any(feature = "lua54", feature = "lua53"))] ffi::LUA_TNUMBER => { - if ffi::lua_isinteger(state, -1) != 0 { - let i = Value::Integer(ffi::lua_tointeger(state, -1)); - ffi::lua_pop(state, 1); - i + let v = if ffi::lua_isinteger(state, -1) != 0 { + Value::Integer(ffi::lua_tointeger(state, -1)) } else { - let n = Value::Number(ffi::lua_tonumber(state, -1)); - ffi::lua_pop(state, 1); - n + Value::Number(ffi::lua_tonumber(state, -1)) + }; + ffi::lua_pop(state, 1); + v + } + + #[cfg(any( + feature = "lua52", + feature = "lua51", + feature = "luajit", + feature = "luau" + ))] + ffi::LUA_TNUMBER => { + let n = ffi::lua_tonumber(state, -1); + ffi::lua_pop(state, 1); + match num_traits::cast(n) { + Some(i) if (n - (i as Number)).abs() < Number::EPSILON => Value::Integer(i), + _ => Value::Number(n), } } diff --git a/tests/tests.rs b/tests/tests.rs index ceaded9..d7a5d65 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -560,7 +560,12 @@ fn test_num_conversion() -> Result<()> { assert_eq!(lua.load("1.0").eval::<f64>()?, 1.0); #[cfg(any(feature = "lua54", feature = "lua53"))] assert_eq!(lua.load("1.0").eval::<String>()?, "1.0"); - #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] + #[cfg(any( + feature = "lua52", + feature = "lua51", + feature = "luajit", + feature = "luau" + ))] assert_eq!(lua.load("1.0").eval::<String>()?, "1"); assert_eq!(lua.load("1.5").eval::<i64>()?, 1); |