summaryrefslogtreecommitdiff
path: root/src/userdata.rs
diff options
context:
space:
mode:
authorAlex Orlenko <zxteam@protonmail.com>2020-01-06 23:59:50 +0000
committerAlex Orlenko <zxteam@protonmail.com>2020-01-07 00:03:03 +0000
commit5eec0ef56ba710e8bcd2e4f32ade865c7b2d23d6 (patch)
tree7eff34c340e9dbfd49ef3acb6f3a36348b72a3f3 /src/userdata.rs
parent831161bfda4fb5bfea306e8ebec6db508a0884c8 (diff)
downloadmlua-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.rs51
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
+ }
+}