diff options
author | Alex Orlenko <zxteam@protonmail.com> | 2020-01-06 23:59:50 +0000 |
---|---|---|
committer | Alex Orlenko <zxteam@protonmail.com> | 2020-01-07 00:03:03 +0000 |
commit | 5eec0ef56ba710e8bcd2e4f32ade865c7b2d23d6 (patch) | |
tree | 7eff34c340e9dbfd49ef3acb6f3a36348b72a3f3 /src/userdata.rs | |
parent | 831161bfda4fb5bfea306e8ebec6db508a0884c8 (diff) | |
download | mlua-5eec0ef56ba710e8bcd2e4f32ade865c7b2d23d6.zip |
Implement PartialEq trait for Value (and subtypes)
Add equals() method to compare values optionally invoking __eq.
Diffstat (limited to 'src/userdata.rs')
-rw-r--r-- | src/userdata.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/userdata.rs b/src/userdata.rs index 8177ad9..32817b6 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -2,7 +2,9 @@ use std::cell::{Ref, RefCell, RefMut}; use crate::error::{Error, Result}; use crate::ffi; +use crate::function::Function; use crate::lua::Lua; +use crate::table::Table; use crate::types::LuaRef; use crate::util::{assert_stack, get_userdata, StackGuard}; use crate::value::{FromLua, FromLuaMulti, ToLua, ToLuaMulti}; @@ -398,6 +400,42 @@ impl<'lua> AnyUserData<'lua> { V::from_lua(res, lua) } + fn get_metatable(&self) -> Result<Table<'lua>> { + unsafe { + let lua = self.0.lua; + let _sg = StackGuard::new(lua.state); + assert_stack(lua.state, 3); + + lua.push_ref(&self.0); + + if ffi::lua_getmetatable(lua.state, -1) == 0 { + return Err(Error::UserDataTypeMismatch); + } + + Ok(Table(lua.pop_ref())) + } + } + + pub(crate) fn equals<T: AsRef<Self>>(&self, other: T) -> Result<bool> { + let other = other.as_ref(); + if self == other { + return Ok(true); + } + + let mt = self.get_metatable()?; + if mt != other.get_metatable()? { + return Ok(false); + } + + if mt.contains_key("__eq")? { + return mt + .get::<_, Function>("__eq")? + .call((self.clone(), other.clone())); + } + + Ok(false) + } + fn inspect<'a, T, R, F>(&'a self, func: F) -> Result<R> where T: 'static + UserData, @@ -428,3 +466,16 @@ impl<'lua> AnyUserData<'lua> { } } } + +impl<'lua> PartialEq for AnyUserData<'lua> { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl<'lua> AsRef<AnyUserData<'lua>> for AnyUserData<'lua> { + #[inline] + fn as_ref(&self) -> &Self { + self + } +} |