summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Orlenko <zxteam@protonmail.com>2022-05-30 19:26:12 +0100
committerAlex Orlenko <zxteam@protonmail.com>2022-05-30 19:26:12 +0100
commita05a58b2588377bcb214f0ef28c1342b3b67dc17 (patch)
tree26bd7329d4c7c3450a7eca0552c42d2303c366be
parent3766cee4ddd70058121b3eb0a5261e4c2557ea0e (diff)
downloadmlua-a05a58b2588377bcb214f0ef28c1342b3b67dc17.zip
Update integer/number coercion logic
-rw-r--r--src/conversion.rs30
-rw-r--r--src/lua.rs28
-rw-r--r--tests/tests.rs7
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,
diff --git a/src/lua.rs b/src/lua.rs
index c6dfcf9..4b1edd6 100644
--- a/src/lua.rs
+++ b/src/lua.rs
@@ -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);