Add pair and ipair metamethods support (lua 5.2/5.3 only)
This commit is contained in:
parent
fd17a01456
commit
143c3a81a7
|
@ -70,6 +70,16 @@ pub enum MetaMethod {
|
||||||
///
|
///
|
||||||
/// This is not an operator, but will be called by methods such as `tostring` and `print`.
|
/// This is not an operator, but will be called by methods such as `tostring` and `print`.
|
||||||
ToString,
|
ToString,
|
||||||
|
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
||||||
|
/// The `__pairs` metamethod.
|
||||||
|
///
|
||||||
|
/// This is not an operator, but it will be called by the built-in `pairs` function.
|
||||||
|
Pairs,
|
||||||
|
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
||||||
|
/// The `__ipairs` metamethod.
|
||||||
|
///
|
||||||
|
/// This is not an operator, but it will be called by the built-in `ipairs` function.
|
||||||
|
IPairs,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetaMethod {
|
impl MetaMethod {
|
||||||
|
@ -105,6 +115,10 @@ impl MetaMethod {
|
||||||
MetaMethod::NewIndex => b"__newindex",
|
MetaMethod::NewIndex => b"__newindex",
|
||||||
MetaMethod::Call => b"__call",
|
MetaMethod::Call => b"__call",
|
||||||
MetaMethod::ToString => b"__tostring",
|
MetaMethod::ToString => b"__tostring",
|
||||||
|
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
||||||
|
MetaMethod::Pairs => b"__pairs",
|
||||||
|
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
||||||
|
MetaMethod::IPairs => b"__ipairs",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,18 @@ fn test_metamethods() -> Result<()> {
|
||||||
Err("no such custom index".to_lua_err())
|
Err("no such custom index".to_lua_err())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
||||||
|
methods.add_meta_method(MetaMethod::IPairs, |lua, data, ()| {
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
let stateless_iter = lua.create_function(|_, (data, i): (MyUserData, i64)| {
|
||||||
|
let i = i + 1;
|
||||||
|
if i <= data.0 {
|
||||||
|
return Ok(mlua::Variadic::from_iter(vec![i, i]));
|
||||||
|
}
|
||||||
|
return Ok(mlua::Variadic::new());
|
||||||
|
})?;
|
||||||
|
Ok((stateless_iter, data.clone(), 0))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,9 +126,29 @@ fn test_metamethods() -> Result<()> {
|
||||||
lua.load("userdata1 + userdata2").eval::<MyUserData>()?.0,
|
lua.load("userdata1 + userdata2").eval::<MyUserData>()?.0,
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
||||||
|
let ipairs_it = {
|
||||||
|
lua.load(
|
||||||
|
r#"
|
||||||
|
function ipairs_it()
|
||||||
|
local r = 0
|
||||||
|
for i, v in ipairs(userdata1) do
|
||||||
|
r = r + v
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.exec()?;
|
||||||
|
globals.get::<_, Function>("ipairs_it")?
|
||||||
|
};
|
||||||
|
|
||||||
assert_eq!(lua.load("userdata1 - userdata2").eval::<MyUserData>()?.0, 4);
|
assert_eq!(lua.load("userdata1 - userdata2").eval::<MyUserData>()?.0, 4);
|
||||||
assert_eq!(lua.load("userdata1:get()").eval::<i64>()?, 7);
|
assert_eq!(lua.load("userdata1:get()").eval::<i64>()?, 7);
|
||||||
assert_eq!(lua.load("userdata2.inner").eval::<i64>()?, 3);
|
assert_eq!(lua.load("userdata2.inner").eval::<i64>()?, 3);
|
||||||
|
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
||||||
|
assert_eq!(ipairs_it.call::<_, i64>(())?, 28);
|
||||||
assert!(lua.load("userdata2.nonexist_field").eval::<()>().is_err());
|
assert!(lua.load("userdata2.nonexist_field").eval::<()>().is_err());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue