From ebfa295aed878b9194c7f81eb918399aa9f00779 Mon Sep 17 00:00:00 2001 From: renderthegreat Date: Fri, 10 Jul 2026 20:32:30 -0500 Subject: [PATCH 1/6] Add HasValueRef trait --- src/buffer.rs | 7 +++++++ src/function.rs | 8 +++++++- src/string.rs | 8 +++++++- src/table.rs | 9 +++++---- src/thread.rs | 8 +++++++- src/traits.rs | 14 +++++++++++--- src/userdata.rs | 8 +++++++- src/value.rs | 26 ++++++++++++++++++++++++++ 8 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index d256c626..a25c20ae 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -4,6 +4,7 @@ use std::io; use serde::ser::{Serialize, Serializer}; use crate::state::RawLua; +use crate::traits::HasValueRef; use crate::types::ValueRef; /// A Luau buffer type. @@ -161,6 +162,12 @@ impl io::Seek for BufferCursor { } } +impl HasValueRef for Buffer { + fn to_vref(&self) -> ValueRef { + self.0 + } +} + #[cfg(feature = "serde")] impl Serialize for Buffer { fn serialize(&self, serializer: S) -> std::result::Result { diff --git a/src/function.rs b/src/function.rs index 8081ec9f..54906413 100644 --- a/src/function.rs +++ b/src/function.rs @@ -81,7 +81,7 @@ use std::{mem, ptr, slice}; use crate::error::{Error, ExternalError, ExternalResult, Result}; use crate::state::Lua; use crate::table::Table; -use crate::traits::{FromLuaMulti, IntoLua, IntoLuaMulti}; +use crate::traits::{FromLuaMulti, HasValueRef, IntoLua, IntoLuaMulti}; use crate::types::{Callback, LuaType, MaybeSend, ValueRef}; use crate::util::{ StackGuard, assert_stack, check_stack, linenumber_to_usize, pop_error, ptr_to_lossy_str, ptr_to_str, @@ -749,6 +749,12 @@ impl IntoLua for WrappedAsyncFunction { } } +impl HasValueRef for Function { + fn to_vref(&self) -> ValueRef { + self.0 + } +} + impl LuaType for Function { const TYPE_ID: c_int = ffi::LUA_TFUNCTION; } diff --git a/src/string.rs b/src/string.rs index 18a40807..980004b9 100644 --- a/src/string.rs +++ b/src/string.rs @@ -10,7 +10,7 @@ use std::{cmp, fmt, mem, slice, str}; use crate::error::{Error, Result}; use crate::state::Lua; -use crate::traits::IntoLua; +use crate::traits::{HasValueRef, IntoLua}; use crate::types::{LuaType, ValueRef}; use crate::value::Value; @@ -215,6 +215,12 @@ impl Hash for LuaString { } } +impl HasValueRef for LuaString { + fn to_vref(&self) -> ValueRef { + self.0 + } +} + #[cfg(feature = "serde")] impl Serialize for LuaString { fn serialize(&self, serializer: S) -> StdResult diff --git a/src/table.rs b/src/table.rs index e93610ff..2a6fff16 100644 --- a/src/table.rs +++ b/src/table.rs @@ -159,7 +159,7 @@ use std::os::raw::c_void; use crate::error::{Error, Result}; use crate::function::Function; use crate::state::{LuaGuard, RawLua, WeakLua}; -use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike}; +use crate::traits::{FromLua, FromLuaMulti, HasValueRef, IntoLua, IntoLuaMulti, ObjectLike}; use crate::types::{Integer, ValueRef}; use crate::util::{StackGuard, assert_stack, check_stack, get_metatable_ptr}; use crate::value::{Nil, Value}; @@ -1219,10 +1219,11 @@ impl ObjectLike for Table { fn to_value(&self) -> Value { Value::Table(self.clone()) } +} - #[inline] - fn weak_lua(&self) -> &WeakLua { - &self.0.lua +impl HasValueRef for Table { + fn to_vref(&self) -> ValueRef { + self.0 } } diff --git a/src/thread.rs b/src/thread.rs index 968be182..03c283e6 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -41,7 +41,7 @@ use std::os::raw::{c_int, c_void}; use crate::error::{Error, Result}; use crate::function::Function; use crate::state::RawLua; -use crate::traits::{FromLuaMulti, IntoLuaMulti}; +use crate::traits::{FromLuaMulti, HasValueRef, IntoLuaMulti}; use crate::types::{LuaType, ValueRef}; use crate::util::{StackGuard, check_stack, error_traceback_thread, pop_error}; @@ -769,6 +769,12 @@ impl fmt::Debug for Thread { } } +impl HasValueRef for Thread { + fn to_vref(&self) -> ValueRef { + self.0 + } +} + impl LuaType for Thread { const TYPE_ID: c_int = ffi::LUA_TTHREAD; } diff --git a/src/traits.rs b/src/traits.rs index 405a95f7..e013ac57 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -10,6 +10,7 @@ use crate::error::{Error, Result}; use crate::multi::MultiValue; use crate::private::Sealed; use crate::state::{Lua, RawLua, WeakLua}; +use crate::types::ValueRef; use crate::util::{check_stack, parse_lookup_path, short_type_name}; use crate::value::Value; @@ -243,10 +244,17 @@ pub trait ObjectLike: Sealed { /// Converts the object to a Lua value. fn to_value(&self) -> Value; +} - /// Gets a reference to the associated Lua state. - #[doc(hidden)] - fn weak_lua(&self) -> &WeakLua; +/// A trait for types that have a [`ValueRef`]. +pub trait HasValueRef: Sized { + /// Convert to a [`ValueRef`]. + fn to_vref(&self) -> ValueRef; +} + +pub trait MaybeHasValueRef: Size { + /// Convert compatiable types to a [`ValueRef`]. + fn maybe_to_vref(&self) -> Option; } pub(crate) trait ShortTypeName { diff --git a/src/userdata.rs b/src/userdata.rs index 912efa22..29c65963 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -14,7 +14,7 @@ use crate::function::Function; use crate::state::Lua; use crate::string::LuaString; use crate::table::{Table, TablePairs}; -use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti}; +use crate::traits::{FromLua, FromLuaMulti, HasValueRef, IntoLua, IntoLuaMulti}; use crate::types::{MaybeSend, MaybeSync, ValueRef}; use crate::util::{StackGuard, check_stack, get_userdata, push_string, short_type_name, take_userdata}; use crate::value::Value; @@ -1121,6 +1121,12 @@ impl AnyUserData { } } +impl HasValueRef for AnyUserData { + fn to_vref(&self) -> ValueRef { + self.0 + } +} + impl fmt::Debug for AnyUserData { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { if fmt.alternate() { diff --git a/src/value.rs b/src/value.rs index d273dad7..9dd810af 100644 --- a/src/value.rs +++ b/src/value.rs @@ -10,6 +10,7 @@ use crate::function::Function; use crate::string::LuaString; use crate::table::Table; use crate::thread::Thread; +use crate::traits::MaybeHasValueRef; use crate::types::{Integer, LightUserData, Number, ValueRef}; use crate::userdata::AnyUserData; use crate::util::{StackGuard, check_stack}; @@ -560,6 +561,31 @@ impl Value { } } +impl MaybeHasValueRef for Value { + fn maybe_to_vref(&self) -> Option { + // Don't use the `_` pattern, as may be over looking in the future causing compatiable types to + // return `None`. + match self { + &Self::Nil => None, + &Self::Boolean(_) => None, + &Self::LightUserData(_) => None, + &Self::Error(_) => None, + &Self::Function(Function(vref)) => Some(vref), + &Self::Integer(_) => None, + &Self::Number(_) => None, + &Self::String(LuaString(vref)) => Some(vref), + &Self::Table(Table(vref)) => Some(vref), + &Self::Thread(Thread(vref, _)) => Some(vref), + #[cfg(feature = "luau")] + &Self::Buffer(Buffer(vref)) => Some(vref), + #[cfg(feature = "luau")] + &Self::Vector(_) => None, + &Self::UserData(AnyUserData(vref)) => Some(vref), + &Self::Other(vref) => Some(vref), + } + } +} + impl fmt::Debug for Value { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { if fmt.alternate() { From 92dc0fb428189a80beddab7127aa4c422b2fd25d Mon Sep 17 00:00:00 2001 From: renderthegreat Date: Fri, 10 Jul 2026 20:44:42 -0500 Subject: [PATCH 2/6] Re-add weak_lua --- src/table.rs | 5 +++++ src/traits.rs | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/table.rs b/src/table.rs index 2a6fff16..ea1c98f0 100644 --- a/src/table.rs +++ b/src/table.rs @@ -1219,6 +1219,11 @@ impl ObjectLike for Table { fn to_value(&self) -> Value { Value::Table(self.clone()) } + + #[inline] + fn weak_lua(&self) -> &WeakLua { + &self.0.lua + } } impl HasValueRef for Table { diff --git a/src/traits.rs b/src/traits.rs index e013ac57..61213b1d 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -244,6 +244,9 @@ pub trait ObjectLike: Sealed { /// Converts the object to a Lua value. fn to_value(&self) -> Value; + + #[doc(hidden)] + fn weak_lua(&self) -> &WeakLua; } /// A trait for types that have a [`ValueRef`]. From 53552d2331b08b185c53353b2f4bf7746dfee819 Mon Sep 17 00:00:00 2001 From: renderthegreat Date: Fri, 10 Jul 2026 20:45:57 -0500 Subject: [PATCH 3/6] Diff-fix --- src/traits.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/traits.rs b/src/traits.rs index 61213b1d..8ea91bb6 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -245,6 +245,7 @@ pub trait ObjectLike: Sealed { /// Converts the object to a Lua value. fn to_value(&self) -> Value; + /// Gets a reference to the associated Lua state. #[doc(hidden)] fn weak_lua(&self) -> &WeakLua; } From a42bb45ebd9c7b76c95f607cfdc07cdb42169981 Mon Sep 17 00:00:00 2001 From: renderthegreat Date: Fri, 10 Jul 2026 20:46:50 -0500 Subject: [PATCH 4/6] ... --- src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/traits.rs b/src/traits.rs index 8ea91bb6..209cd21f 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -256,7 +256,7 @@ pub trait HasValueRef: Sized { fn to_vref(&self) -> ValueRef; } -pub trait MaybeHasValueRef: Size { +pub trait MaybeHasValueRef: Sized { /// Convert compatiable types to a [`ValueRef`]. fn maybe_to_vref(&self) -> Option; } From 2566eaa65e0374f63bd82254ae64aa1ad0328c5a Mon Sep 17 00:00:00 2001 From: renderthegreat Date: Fri, 10 Jul 2026 20:50:17 -0500 Subject: [PATCH 5/6] ... --- src/buffer.rs | 4 ++-- src/function.rs | 4 ++-- src/string.rs | 4 ++-- src/table.rs | 4 ++-- src/thread.rs | 4 ++-- src/traits.rs | 4 ++-- src/userdata.rs | 4 ++-- src/value.rs | 30 +++++++++++++++--------------- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index a25c20ae..4552431e 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -163,8 +163,8 @@ impl io::Seek for BufferCursor { } impl HasValueRef for Buffer { - fn to_vref(&self) -> ValueRef { - self.0 + fn to_vref(&self) -> &ValueRef { + &self.0 } } diff --git a/src/function.rs b/src/function.rs index 54906413..cb2118b5 100644 --- a/src/function.rs +++ b/src/function.rs @@ -750,8 +750,8 @@ impl IntoLua for WrappedAsyncFunction { } impl HasValueRef for Function { - fn to_vref(&self) -> ValueRef { - self.0 + fn to_vref(&self) -> &ValueRef { + &self.0 } } diff --git a/src/string.rs b/src/string.rs index 980004b9..b40f9a0e 100644 --- a/src/string.rs +++ b/src/string.rs @@ -216,8 +216,8 @@ impl Hash for LuaString { } impl HasValueRef for LuaString { - fn to_vref(&self) -> ValueRef { - self.0 + fn to_vref(&self) -> &ValueRef { + &self.0 } } diff --git a/src/table.rs b/src/table.rs index ea1c98f0..59880ad9 100644 --- a/src/table.rs +++ b/src/table.rs @@ -1227,8 +1227,8 @@ impl ObjectLike for Table { } impl HasValueRef for Table { - fn to_vref(&self) -> ValueRef { - self.0 + fn to_vref(&self) -> &ValueRef { + &self.0 } } diff --git a/src/thread.rs b/src/thread.rs index 03c283e6..a9d61066 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -770,8 +770,8 @@ impl fmt::Debug for Thread { } impl HasValueRef for Thread { - fn to_vref(&self) -> ValueRef { - self.0 + fn to_vref(&self) -> &ValueRef { + &self.0 } } diff --git a/src/traits.rs b/src/traits.rs index 209cd21f..c3ae91a3 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -253,12 +253,12 @@ pub trait ObjectLike: Sealed { /// A trait for types that have a [`ValueRef`]. pub trait HasValueRef: Sized { /// Convert to a [`ValueRef`]. - fn to_vref(&self) -> ValueRef; + fn to_vref(&self) -> &ValueRef; } pub trait MaybeHasValueRef: Sized { /// Convert compatiable types to a [`ValueRef`]. - fn maybe_to_vref(&self) -> Option; + fn maybe_to_vref(&self) -> Option<&ValueRef>; } pub(crate) trait ShortTypeName { diff --git a/src/userdata.rs b/src/userdata.rs index 29c65963..3918c623 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -1122,8 +1122,8 @@ impl AnyUserData { } impl HasValueRef for AnyUserData { - fn to_vref(&self) -> ValueRef { - self.0 + fn to_vref(&self) -> &ValueRef { + &self.0 } } diff --git a/src/value.rs b/src/value.rs index 9dd810af..1ef196ee 100644 --- a/src/value.rs +++ b/src/value.rs @@ -562,26 +562,26 @@ impl Value { } impl MaybeHasValueRef for Value { - fn maybe_to_vref(&self) -> Option { + fn maybe_to_vref(&self) -> Option<&ValueRef> { // Don't use the `_` pattern, as may be over looking in the future causing compatiable types to // return `None`. match self { - &Self::Nil => None, - &Self::Boolean(_) => None, - &Self::LightUserData(_) => None, - &Self::Error(_) => None, - &Self::Function(Function(vref)) => Some(vref), - &Self::Integer(_) => None, - &Self::Number(_) => None, - &Self::String(LuaString(vref)) => Some(vref), - &Self::Table(Table(vref)) => Some(vref), - &Self::Thread(Thread(vref, _)) => Some(vref), + Self::Nil => None, + Self::Boolean(_) => None, + Self::LightUserData(_) => None, + Self::Error(_) => None, + Self::Function(Function(vref)) => Some(vref), + Self::Integer(_) => None, + Self::Number(_) => None, + Self::String(LuaString(vref)) => Some(vref), + Self::Table(Table(vref)) => Some(vref), + Self::Thread(Thread(vref, _)) => Some(vref), #[cfg(feature = "luau")] - &Self::Buffer(Buffer(vref)) => Some(vref), + Self::Buffer(Buffer(vref)) => Some(vref), #[cfg(feature = "luau")] - &Self::Vector(_) => None, - &Self::UserData(AnyUserData(vref)) => Some(vref), - &Self::Other(vref) => Some(vref), + Self::Vector(_) => None, + Self::UserData(AnyUserData(vref)) => Some(vref), + Self::Other(vref) => Some(vref), } } } From f343889ac8f3f9feb6460a5b03853cc3654edcfd Mon Sep 17 00:00:00 2001 From: renderthegreat Date: Fri, 10 Jul 2026 20:53:58 -0500 Subject: [PATCH 6/6] ... --- src/value.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/value.rs b/src/value.rs index 1ef196ee..3e3fe3f2 100644 --- a/src/value.rs +++ b/src/value.rs @@ -563,6 +563,8 @@ impl Value { impl MaybeHasValueRef for Value { fn maybe_to_vref(&self) -> Option<&ValueRef> { + #[cfg(feature = "luau")] + use crate::buffer::Buffer; // Don't use the `_` pattern, as may be over looking in the future causing compatiable types to // return `None`. match self {