Skip to content

Commit 3ca7b49

Browse files
committed
Implement IntoLua for &Value
1 parent 1754226 commit 3ca7b49

File tree

3 files changed

+55
-44
lines changed

3 files changed

+55
-44
lines changed

src/conversion.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ impl<'lua> IntoLua<'lua> for Value<'lua> {
3333
}
3434
}
3535

36+
impl<'lua> IntoLua<'lua> for &Value<'lua> {
37+
#[inline]
38+
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
39+
Ok(self.clone())
40+
}
41+
42+
#[inline]
43+
unsafe fn push_into_stack(self, lua: &'lua Lua) -> Result<()> {
44+
lua.push_value_ref(self)
45+
}
46+
}
47+
3648
impl<'lua> FromLua<'lua> for Value<'lua> {
3749
#[inline]
3850
fn from_lua(lua_value: Value<'lua>, _: &'lua Lua) -> Result<Self> {

src/lua.rs

Lines changed: 26 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,73 +2269,55 @@ impl Lua {
22692269
extra.app_data.remove()
22702270
}
22712271

2272+
/// Pushes a value that implements `IntoLua` onto the Lua stack.
2273+
///
2274+
/// Uses 2 stack spaces, does not call checkstack.
22722275
#[doc(hidden)]
22732276
#[inline(always)]
22742277
pub unsafe fn push<'lua>(&'lua self, value: impl IntoLua<'lua>) -> Result<()> {
22752278
value.push_into_stack(self)
22762279
}
22772280

2278-
/// Pushes a value onto the Lua stack.
2281+
/// Pushes a `Value` onto the Lua stack.
22792282
///
22802283
/// Uses 2 stack spaces, does not call checkstack.
22812284
#[doc(hidden)]
22822285
pub unsafe fn push_value(&self, value: Value) -> Result<()> {
2286+
if let Value::Error(err) = value {
2287+
let protect = !self.unlikely_memory_error();
2288+
return push_gc_userdata(self.state(), WrappedFailure::Error(err), protect);
2289+
}
2290+
self.push_value_ref(&value)
2291+
}
2292+
2293+
/// Pushes a `&Value` (by reference) onto the Lua stack.
2294+
///
2295+
/// Similar to [`Lua::push_value`], uses 2 stack spaces, does not call checkstack.
2296+
pub(crate) unsafe fn push_value_ref(&self, value: &Value) -> Result<()> {
22832297
let state = self.state();
22842298
match value {
2285-
Value::Nil => {
2286-
ffi::lua_pushnil(state);
2287-
}
2288-
2289-
Value::Boolean(b) => {
2290-
ffi::lua_pushboolean(state, b as c_int);
2291-
}
2292-
2293-
Value::LightUserData(ud) => {
2294-
ffi::lua_pushlightuserdata(state, ud.0);
2295-
}
2296-
2297-
Value::Integer(i) => {
2298-
ffi::lua_pushinteger(state, i);
2299-
}
2300-
2301-
Value::Number(n) => {
2302-
ffi::lua_pushnumber(state, n);
2303-
}
2304-
2299+
Value::Nil => ffi::lua_pushnil(state),
2300+
Value::Boolean(b) => ffi::lua_pushboolean(state, *b as c_int),
2301+
Value::LightUserData(ud) => ffi::lua_pushlightuserdata(state, ud.0),
2302+
Value::Integer(i) => ffi::lua_pushinteger(state, *i),
2303+
Value::Number(n) => ffi::lua_pushnumber(state, *n),
23052304
#[cfg(feature = "luau")]
23062305
Value::Vector(v) => {
23072306
#[cfg(not(feature = "luau-vector4"))]
23082307
ffi::lua_pushvector(state, v.x(), v.y(), v.z());
23092308
#[cfg(feature = "luau-vector4")]
23102309
ffi::lua_pushvector(state, v.x(), v.y(), v.z(), v.w());
23112310
}
2312-
2313-
Value::String(s) => {
2314-
self.push_ref(&s.0);
2315-
}
2316-
2317-
Value::Table(t) => {
2318-
self.push_ref(&t.0);
2319-
}
2320-
2321-
Value::Function(f) => {
2322-
self.push_ref(&f.0);
2323-
}
2324-
2325-
Value::Thread(t) => {
2326-
self.push_ref(&t.0);
2327-
}
2328-
2329-
Value::UserData(ud) => {
2330-
self.push_ref(&ud.0);
2331-
}
2332-
2311+
Value::String(s) => self.push_ref(&s.0),
2312+
Value::Table(t) => self.push_ref(&t.0),
2313+
Value::Function(f) => self.push_ref(&f.0),
2314+
Value::Thread(t) => self.push_ref(&t.0),
2315+
Value::UserData(ud) => self.push_ref(&ud.0),
23332316
Value::Error(err) => {
23342317
let protect = !self.unlikely_memory_error();
2335-
push_gc_userdata(state, WrappedFailure::Error(err), protect)?;
2318+
push_gc_userdata(state, WrappedFailure::Error(err.clone()), protect)?;
23362319
}
23372320
}
2338-
23392321
Ok(())
23402322
}
23412323

tests/conversion.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ use std::ffi::{CStr, CString};
55
use maplit::{btreemap, btreeset, hashmap, hashset};
66
use mlua::{AnyUserData, Error, Function, IntoLua, Lua, Result, Table, Thread, UserDataRef, Value};
77

8+
#[test]
9+
fn test_value_into_lua() -> Result<()> {
10+
let lua = Lua::new();
11+
12+
// Direct conversion
13+
let v = Value::Boolean(true);
14+
let v2 = (&v).into_lua(&lua)?;
15+
assert_eq!(v, v2);
16+
17+
// Push into stack
18+
let table = lua.create_table()?;
19+
table.set("v", &v)?;
20+
assert_eq!(v, table.get::<_, Value>("v")?);
21+
22+
Ok(())
23+
}
24+
825
#[test]
926
fn test_string_into_lua() -> Result<()> {
1027
let lua = Lua::new();

0 commit comments

Comments
 (0)