Add Value::to_pointer() function.

Closes #165 and #166.
This commit is contained in:
Alex Orlenko 2022-05-18 13:15:08 +01:00
parent 8cd594c609
commit bcf2cbea37
No known key found for this signature in database
GPG key ID: 4C150C250863B96D
2 changed files with 38 additions and 5 deletions

View file

@ -1,5 +1,6 @@
use std::iter::{self, FromIterator};
use std::{slice, str, vec};
use std::os::raw::c_void;
use std::{ptr, slice, str, vec};
#[cfg(feature = "serialize")]
use {
@ -9,6 +10,7 @@ use {
};
use crate::error::{Error, Result};
use crate::ffi;
use crate::function::Function;
use crate::lua::Lua;
use crate::string::String;
@ -93,6 +95,29 @@ impl<'lua> Value<'lua> {
_ => Ok(self == other.as_ref()),
}
}
/// Converts the value to a generic C pointer.
///
/// The value can be a userdata, a table, a thread, a string, or a function; otherwise it returns NULL.
/// Different objects will give different pointers.
/// There is no way to convert the pointer back to its original value.
///
/// Typically this function is used only for hashing and debug information.
pub fn to_pointer(&self) -> *const c_void {
unsafe {
match self {
Value::LightUserData(ud) => ud.0,
Value::String(String(v))
| Value::Table(Table(v))
| Value::Function(Function(v))
| Value::Thread(Thread(v))
| Value::UserData(AnyUserData(v)) => v
.lua
.ref_thread_exec(|refthr| ffi::lua_topointer(refthr, v.index)),
_ => ptr::null(),
}
}
}
}
impl<'lua> PartialEq for Value<'lua> {

View file

@ -1,3 +1,5 @@
use std::ptr;
use mlua::{Lua, Result, Value};
#[test]
@ -41,17 +43,23 @@ fn test_value_eq() -> Result<()> {
let thread2: Value = globals.get("thread2")?;
assert!(table1 != table2);
assert!(table1.equals(table2)?);
assert!(table1.equals(&table2)?);
assert!(string1 == string2);
assert!(string1.equals(string2)?);
assert!(string1.equals(&string2)?);
assert!(num1 == num2);
assert!(num1.equals(num2)?);
assert!(num1 != num3);
assert!(func1 == func2);
assert!(func1 != func3);
assert!(!func1.equals(func3)?);
assert!(!func1.equals(&func3)?);
assert!(thread1 == thread2);
assert!(thread1.equals(thread2)?);
assert!(thread1.equals(&thread2)?);
assert!(!table1.to_pointer().is_null());
assert!(!ptr::eq(table1.to_pointer(), table2.to_pointer()));
assert!(ptr::eq(string1.to_pointer(), string2.to_pointer()));
assert!(ptr::eq(func1.to_pointer(), func2.to_pointer()));
assert!(num1.to_pointer().is_null());
Ok(())
}