diff --git a/src/userdata.rs b/src/userdata.rs index 68aa208..82ec52b 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -10,7 +10,7 @@ use crate::lua::Lua; use crate::table::Table; use crate::types::{LuaRef, MaybeSend}; use crate::util::{assert_stack, get_userdata, StackGuard}; -use crate::value::{FromLua, FromLuaMulti, ToLua, ToLuaMulti}; +use crate::value::{FromLua, FromLuaMulti, ToLua, ToLuaMulti, Value}; /// Kinds of metamethods that can be overridden. /// @@ -460,6 +460,22 @@ impl<'lua> AnyUserData<'lua> { V::from_lua(res, lua) } + /// Checks for a metamethod in this `AnyUserData` + pub fn has_metamethod(&self, method: MetaMethod) -> Result { + match self.get_metatable() { + Ok(mt) => { + let name = self.0.lua.create_string(method.name())?; + if let Value::Nil = mt.raw_get(name)? { + Ok(false) + } else { + Ok(true) + } + } + Err(Error::UserDataTypeMismatch) => Ok(false), + Err(e) => Err(e), + } + } + fn get_metatable(&self) -> Result> { unsafe { let lua = self.0.lua; diff --git a/tests/userdata.rs b/tests/userdata.rs index 8ed7232..1a0ad8b 100644 --- a/tests/userdata.rs +++ b/tests/userdata.rs @@ -166,6 +166,12 @@ fn test_metamethods() -> Result<()> { assert!(userdata2 != userdata3); // because references are differ assert!(userdata2.equals(userdata3)?); + let userdata1: AnyUserData = globals.get("userdata1")?; + assert!(userdata1.has_metamethod(MetaMethod::Add)?); + assert!(userdata1.has_metamethod(MetaMethod::Sub)?); + assert!(userdata1.has_metamethod(MetaMethod::Index)?); + assert!(!userdata1.has_metamethod(MetaMethod::Pow)?); + Ok(()) }