Skip to content

Commit c6ecd19

Browse files
committed
Add AnyUserData::type_id method
1 parent 205f57a commit c6ecd19

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

src/state/raw.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,8 @@ impl RawLua {
10361036
// Returns `TypeId` for the userdata ref, checking that it's registered and not destructed.
10371037
//
10381038
// Returns `None` if the userdata is registered but non-static.
1039-
pub(crate) unsafe fn get_userdata_ref_type_id(&self, vref: &ValueRef) -> Result<Option<TypeId>> {
1040-
self.get_userdata_type_id_inner(self.ref_thread(), vref.index)
1039+
pub(crate) fn get_userdata_ref_type_id(&self, vref: &ValueRef) -> Result<Option<TypeId>> {
1040+
unsafe { self.get_userdata_type_id_inner(self.ref_thread(), vref.index) }
10411041
}
10421042

10431043
// Same as `get_userdata_ref_type_id` but assumes the userdata is already on the stack.

src/userdata.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,9 @@ impl AnyUserData {
620620
/// Checks whether the type of this userdata is `T`.
621621
#[inline]
622622
pub fn is<T: 'static>(&self) -> bool {
623-
self.inspect::<T, _, _>(|_| Ok(())).is_ok()
623+
let type_id = self.type_id();
624+
// We do not use wrapped types here, rather prefer to check the "real" type of the userdata
625+
matches!(type_id, Some(type_id) if type_id == TypeId::of::<T>())
624626
}
625627

626628
/// Borrow this userdata immutably if it is of type `T`.
@@ -908,6 +910,15 @@ impl AnyUserData {
908910
self.0.to_pointer()
909911
}
910912

913+
/// Returns [`TypeId`] of this userdata if it is registered and `'static`.
914+
///
915+
/// This method is not available for scoped userdata.
916+
#[inline]
917+
pub fn type_id(&self) -> Option<TypeId> {
918+
let lua = self.0.lua.lock();
919+
lua.get_userdata_ref_type_id(&self.0).ok().flatten()
920+
}
921+
911922
/// Returns a type name of this `UserData` (from a metatable field).
912923
pub(crate) fn type_name(&self) -> Result<Option<StdString>> {
913924
let lua = self.0.lua.lock();

tests/userdata.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::any::TypeId;
12
use std::collections::HashMap;
23
use std::string::String as StdString;
34
use std::sync::Arc;
@@ -23,9 +24,11 @@ fn test_userdata() -> Result<()> {
2324
let userdata2 = lua.create_userdata(UserData2(Box::new(2)))?;
2425

2526
assert!(userdata1.is::<UserData1>());
27+
assert!(userdata1.type_id() == Some(TypeId::of::<UserData1>()));
2628
assert!(!userdata1.is::<UserData2>());
2729
assert!(userdata2.is::<UserData2>());
2830
assert!(!userdata2.is::<UserData1>());
31+
assert!(userdata2.type_id() == Some(TypeId::of::<UserData2>()));
2932

3033
assert_eq!(userdata1.borrow::<UserData1>()?.0, 1);
3134
assert_eq!(*userdata2.borrow::<UserData2>()?.0, 2);

0 commit comments

Comments
 (0)