From e265633fb3f9f7fad539a9a1dcb5c950d2f76262 Mon Sep 17 00:00:00 2001 From: kyren Date: Fri, 26 May 2017 23:49:12 -0400 Subject: [PATCH] Callback versions of table functions --- src/lua.rs | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/lua.rs b/src/lua.rs index 3464e60..8ecfd20 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -195,12 +195,15 @@ impl<'lua> LuaTable<'lua> { } } - pub fn pairs, V: FromLua<'lua>>(&self) -> LuaResult> { + /// Loop over each key, value pair in the table + pub fn for_each_pair(&self, mut f: F) -> LuaResult<()> + where K: FromLua<'lua>, + V: FromLua<'lua>, + F: FnMut(K, V) + { let lua = self.0.lua; unsafe { stack_guard(lua.state, 0, || { - let mut pairs = Vec::new(); - check_stack(lua.state, 4)?; lua.push_ref(lua.state, &self.0); ffi::lua_pushnil(lua.state); @@ -209,21 +212,22 @@ impl<'lua> LuaTable<'lua> { ffi::lua_pushvalue(lua.state, -2); let key = K::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); - Ok(pairs) + Ok(()) }) } } - /// Strictly interpret the table as an array, and fail if it is not a proper lua array. - pub fn array_values>(&self) -> LuaResult> { + /// Loop over the table, strictly interpreting the table as an array, and + /// fail if it is not a proper lua array. + pub fn for_each_array_value, F: FnMut(V)>(&self, mut f: F) -> LuaResult<()> { let lua = self.0.lua; unsafe { stack_guard(lua.state, 0, || { - let mut values = Vec::new(); + let mut count = 0; check_stack(lua.state, 4)?; lua.push_ref(lua.state, &self.0); @@ -246,17 +250,33 @@ impl<'lua> LuaTable<'lua> { } // Skip missing keys - while values.len() < (i - 1) as usize { - values.push(V::from_lua(LuaNil, lua)?); + while count < (i - 1) as usize { + 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); - Ok(values) + Ok(()) }) } } + + /// Collect all the pairs in the table into a Vec + pub fn pairs, V: FromLua<'lua>>(&self) -> LuaResult> { + 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>(&self) -> LuaResult> { + let mut values = Vec::new(); + self.for_each_array_value(|v| values.push(v))?; + Ok(values) + } } /// Handle to an an internal lua function