Add `Table:is_empty()` function
This commit is contained in:
parent
b169031d4e
commit
85f17a269d
38
src/table.rs
38
src/table.rs
|
@ -45,7 +45,6 @@ impl OwnedTable {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::len_without_is_empty)]
|
||||
impl<'lua> Table<'lua> {
|
||||
/// Sets a key-value pair in the table.
|
||||
///
|
||||
|
@ -150,11 +149,15 @@ impl<'lua> Table<'lua> {
|
|||
}
|
||||
|
||||
/// Checks whether the table contains a non-nil value for `key`.
|
||||
///
|
||||
/// This might invoke the `__index` metamethod.
|
||||
pub fn contains_key<K: IntoLua<'lua>>(&self, key: K) -> Result<bool> {
|
||||
Ok(self.get::<_, Value>(key)? != Value::Nil)
|
||||
}
|
||||
|
||||
/// Appends a value to the back of the table.
|
||||
///
|
||||
/// This might invoke the `__len` and `__newindex` metamethods.
|
||||
pub fn push<V: IntoLua<'lua>>(&self, value: V) -> Result<()> {
|
||||
// Fast track
|
||||
if !self.has_metatable() {
|
||||
|
@ -179,6 +182,8 @@ impl<'lua> Table<'lua> {
|
|||
}
|
||||
|
||||
/// Removes the last element from the table and returns it.
|
||||
///
|
||||
/// This might invoke the `__len` and `__newindex` metamethods.
|
||||
pub fn pop<V: FromLua<'lua>>(&self) -> Result<V> {
|
||||
// Fast track
|
||||
if !self.has_metatable() {
|
||||
|
@ -492,6 +497,32 @@ impl<'lua> Table<'lua> {
|
|||
unsafe { ffi::lua_rawlen(ref_thread, self.0.index) as Integer }
|
||||
}
|
||||
|
||||
/// Returns `true` if the table is empty, without invoking metamethods.
|
||||
///
|
||||
/// It checks both the array part and the hash part.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
// Check array part
|
||||
if self.raw_len() != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check hash part
|
||||
let lua = self.0.lua;
|
||||
let state = lua.state();
|
||||
unsafe {
|
||||
let _sg = StackGuard::new(state);
|
||||
assert_stack(state, 4);
|
||||
|
||||
lua.push_ref(&self.0);
|
||||
ffi::lua_pushnil(state);
|
||||
if ffi::lua_next(state, -2) != 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns a reference to the metatable of this table, or `None` if no metatable is set.
|
||||
///
|
||||
/// Unlike the `getmetatable` Lua function, this method ignores the `__metatable` field.
|
||||
|
@ -717,10 +748,11 @@ impl<'lua> Table<'lua> {
|
|||
lua.push_ref(&self.0);
|
||||
lua.push_value(value)?;
|
||||
|
||||
let idx = idx.try_into().unwrap();
|
||||
if lua.unlikely_memory_error() {
|
||||
ffi::lua_rawseti(state, -2, idx as _);
|
||||
ffi::lua_rawseti(state, -2, idx);
|
||||
} else {
|
||||
protect_lua!(state, 2, 0, |state| ffi::lua_rawseti(state, -2, idx as _))?;
|
||||
protect_lua!(state, 2, 0, |state| ffi::lua_rawseti(state, -2, idx))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use mlua::{Error, Lua, Nil, Result, Table, TableExt, Value};
|
||||
|
||||
#[test]
|
||||
fn test_set_get() -> Result<()> {
|
||||
fn test_globals_set_get() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let globals = lua.globals();
|
||||
|
@ -43,6 +43,7 @@ fn test_table() -> Result<()> {
|
|||
let table3 = globals.get::<_, Table>("table3")?;
|
||||
|
||||
assert_eq!(table1.len()?, 5);
|
||||
assert!(!table1.is_empty());
|
||||
assert_eq!(
|
||||
table1
|
||||
.clone()
|
||||
|
@ -60,6 +61,7 @@ fn test_table() -> Result<()> {
|
|||
assert_eq!(table1, [1, 2, 3, 4, 5]);
|
||||
|
||||
assert_eq!(table2.len()?, 0);
|
||||
assert!(table2.is_empty());
|
||||
assert_eq!(
|
||||
table2
|
||||
.clone()
|
||||
|
@ -192,8 +194,10 @@ fn test_table_clear() -> Result<()> {
|
|||
)
|
||||
.eval::<Table>()?;
|
||||
assert_eq!(t2.raw_len(), 3);
|
||||
assert!(!t2.is_empty());
|
||||
t2.clear()?;
|
||||
assert_eq!(t2.raw_len(), 0);
|
||||
assert!(t2.is_empty());
|
||||
assert_eq!(t2.raw_get::<_, Value>("a")?, Value::Nil);
|
||||
assert_ne!(t2.get_metatable(), None);
|
||||
|
||||
|
|
Loading…
Reference in New Issue