Callback versions of table functions

This commit is contained in:
kyren 2017-05-26 23:49:12 -04:00
parent 53b001cfce
commit e265633fb3

View file

@ -195,12 +195,15 @@ impl<'lua> LuaTable<'lua> {
} }
} }
pub fn pairs<K: FromLua<'lua>, V: FromLua<'lua>>(&self) -> LuaResult<Vec<(K, V)>> { /// Loop over each key, value pair in the table
pub fn for_each_pair<K, V, F>(&self, mut f: F) -> LuaResult<()>
where K: FromLua<'lua>,
V: FromLua<'lua>,
F: FnMut(K, V)
{
let lua = self.0.lua; let lua = self.0.lua;
unsafe { unsafe {
stack_guard(lua.state, 0, || { stack_guard(lua.state, 0, || {
let mut pairs = Vec::new();
check_stack(lua.state, 4)?; check_stack(lua.state, 4)?;
lua.push_ref(lua.state, &self.0); lua.push_ref(lua.state, &self.0);
ffi::lua_pushnil(lua.state); ffi::lua_pushnil(lua.state);
@ -209,21 +212,22 @@ impl<'lua> LuaTable<'lua> {
ffi::lua_pushvalue(lua.state, -2); ffi::lua_pushvalue(lua.state, -2);
let key = K::from_lua(lua.pop_value(lua.state)?, lua)?; let key = K::from_lua(lua.pop_value(lua.state)?, lua)?;
let value = V::from_lua(lua.pop_value(lua.state)?, lua)?; let value = V::from_lua(lua.pop_value(lua.state)?, lua)?;
pairs.push((key, value)); f(key, value);
} }
ffi::lua_pop(lua.state, 1); ffi::lua_pop(lua.state, 1);
Ok(pairs) Ok(())
}) })
} }
} }
/// Strictly interpret the table as an array, and fail if it is not a proper lua array. /// Loop over the table, strictly interpreting the table as an array, and
pub fn array_values<V: FromLua<'lua>>(&self) -> LuaResult<Vec<V>> { /// fail if it is not a proper lua array.
pub fn for_each_array_value<V: FromLua<'lua>, F: FnMut(V)>(&self, mut f: F) -> LuaResult<()> {
let lua = self.0.lua; let lua = self.0.lua;
unsafe { unsafe {
stack_guard(lua.state, 0, || { stack_guard(lua.state, 0, || {
let mut values = Vec::new(); let mut count = 0;
check_stack(lua.state, 4)?; check_stack(lua.state, 4)?;
lua.push_ref(lua.state, &self.0); lua.push_ref(lua.state, &self.0);
@ -246,17 +250,33 @@ impl<'lua> LuaTable<'lua> {
} }
// Skip missing keys // Skip missing keys
while values.len() < (i - 1) as usize { while count < (i - 1) as usize {
values.push(V::from_lua(LuaNil, lua)?); f(V::from_lua(LuaNil, lua)?);
count += 1;
} }
values.push(V::from_lua(lua.pop_value(lua.state)?, lua)?); f(V::from_lua(lua.pop_value(lua.state)?, lua)?);
count += 1;
} }
ffi::lua_pop(lua.state, 1); ffi::lua_pop(lua.state, 1);
Ok(values) Ok(())
}) })
} }
} }
/// Collect all the pairs in the table into a Vec
pub fn pairs<K: FromLua<'lua>, V: FromLua<'lua>>(&self) -> LuaResult<Vec<(K, V)>> {
let mut pairs = Vec::new();
self.for_each_pair(|k, v| pairs.push((k, v)))?;
Ok(pairs)
}
/// Collect all the values in an array-like table into a Vec
pub fn array_values<V: FromLua<'lua>>(&self) -> LuaResult<Vec<V>> {
let mut values = Vec::new();
self.for_each_array_value(|v| values.push(v))?;
Ok(values)
}
} }
/// Handle to an an internal lua function /// Handle to an an internal lua function