Add Table::raw*

This commit is contained in:
SeanOMik 2024-01-23 20:28:19 -05:00
parent 3d61349bf7
commit 6a0393f346
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
2 changed files with 87 additions and 3 deletions

View File

@ -79,6 +79,10 @@ fn main() -> Result<()> {
assert_eq!(num, 50); assert_eq!(num, 50);
println!("Did math in lua and got 50!"); println!("Did math in lua and got 50!");
unsafe {
assert_eq!(lua::lua_gettop(lua.state_ptr()), 0); // ensure that nothing is left on the stack
}
Ok(()) Ok(())
} }
@ -171,7 +175,9 @@ impl<'a> FromLuaStack<'a> for i32 {
let s = state.state_ptr(); let s = state.state_ptr();
if lua::lua_isnumber(s, -1) == 1 { if lua::lua_isnumber(s, -1) == 1 {
Ok(lua::lua_tonumber(s, -1) as i32) let v = lua::lua_tonumber(s, -1) as i32;
lua::lua_pop(s, -1);
Ok(v)
} else { } else {
let lua_ty = lua_type(s, -1); let lua_ty = lua_type(s, -1);
let typec = CStr::from_ptr(lua_typename(s, lua_ty)); let typec = CStr::from_ptr(lua_typename(s, lua_ty));

View File

@ -10,6 +10,7 @@ pub struct Table<'a> {
} }
impl<'a> Table<'a> { impl<'a> Table<'a> {
/// Create a new table
pub fn new(state: &'a State) -> Result<Self> { pub fn new(state: &'a State) -> Result<Self> {
let lref = unsafe { let lref = unsafe {
state.ensure_stack(1)?; state.ensure_stack(1)?;
@ -25,6 +26,7 @@ impl<'a> Table<'a> {
}) })
} }
/// Construct a table with a lua reference to one.
pub fn with_ref(state: &'a State, lua_ref: LuaRef) -> Result<Self> { pub fn with_ref(state: &'a State, lua_ref: LuaRef) -> Result<Self> {
let s = state.state_ptr(); let s = state.state_ptr();
@ -42,6 +44,9 @@ impl<'a> Table<'a> {
}) })
} }
/// Set a key to a value in the table.
///
/// This may trigger the `__newindex` metamethod, see [`Table::raw_set`]
pub fn set<K, V>(&self, key: K, val: V) -> Result<()> pub fn set<K, V>(&self, key: K, val: V) -> Result<()>
where where
K: PushToLuaStack, K: PushToLuaStack,
@ -62,6 +67,9 @@ impl<'a> Table<'a> {
Ok(()) Ok(())
} }
/// Get a value from the table.
///
/// This may trigger the `__index` metamethod, see [`Table::raw_get`]
pub fn get<K, V>(&'a self, key: K) -> Result<V> pub fn get<K, V>(&'a self, key: K) -> Result<V>
where where
K: PushToLuaStack, K: PushToLuaStack,
@ -72,10 +80,80 @@ impl<'a> Table<'a> {
self.lref.push_to_lua_stack(self.state)?; self.lref.push_to_lua_stack(self.state)?;
key.push_to_lua_stack(self.state)?; key.push_to_lua_stack(self.state)?;
lua::lua_gettable(s, -2); // table[key] is at top of stack lua::lua_gettable(s, -2); // table[key] is at top of stack
V::from_lua_stack(self.state)
let top = lua::lua_gettop(s);
let val = V::from_lua_stack(self.state)?;
let new_top = lua::lua_gettop(s);
debug_assert!(new_top < top, "V::from_lua_stack did not remove anything from the stack!");
Ok(val)
}
} }
//todo!() /// Returns the length of the table.
///
/// This may trigger the `__len` metamethod, see [`Table::raw_len`]
pub fn len(&self) -> Result<u64> {
let s = self.state.state_ptr();
unsafe {
self.lref.push_to_lua_stack(self.state)?;
lua::lua_len(s, -1);
let len = lua::lua_tonumber(s, -1);
lua::lua_pop(self.state.state_ptr(), -1);
Ok(len as u64)
}
}
/// Set a key to a value in the table without calling any meta methods.
pub fn raw_set<K, V>(&self, key: K, val: V) -> Result<()>
where
K: PushToLuaStack,
V: PushToLuaStack
{
let s = self.state.state_ptr();
unsafe {
self.state.ensure_stack(3)?;
self.lref.push_to_lua_stack(self.state)?;
key.push_to_lua_stack(self.state)?;
val.push_to_lua_stack(self.state)?;
lua::lua_rawset(s, -3);
lua::lua_pop(self.state.state_ptr(), -1);
}
Ok(())
}
/// Get a value from the table without calling any meta methods.
pub fn raw_get<K, V>(&'a self, key: K) -> Result<V>
where
K: PushToLuaStack,
V: FromLuaStack<'a>,
{
let s = self.state.state_ptr();
unsafe {
self.lref.push_to_lua_stack(self.state)?;
key.push_to_lua_stack(self.state)?;
lua::lua_rawget(s, -2); // table[key] is at top of stack
V::from_lua_stack(self.state)
}
}
/// Get the length of the table without calling any meta methods.
pub fn raw_len(&self) -> Result<u64> {
let s = self.state.state_ptr();
unsafe {
self.lref.push_to_lua_stack(self.state)?;
lua::lua_rawlen(s, -1);
let len = lua::lua_tonumber(s, -1);
lua::lua_pop(self.state.state_ptr(), -1);
Ok(len as u64)
}
} }
} }