Don't use any metamethods in `Table::sequence_values()` iterator.

This is matches with `Table::pair()` iterator.
Remove `Table::raw_sequence_values()` iterator.
This commit is contained in:
Alex Orlenko 2023-06-26 10:46:59 +01:00
parent 399e469328
commit b169031d4e
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
4 changed files with 11 additions and 37 deletions

View File

@ -709,7 +709,7 @@ impl<'lua, T: Eq + Hash + FromLua<'lua>, S: BuildHasher + Default> FromLua<'lua>
#[inline]
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
match value {
Value::Table(table) if table.len()? > 0 => table.sequence_values().collect(),
Value::Table(table) if table.raw_len() > 0 => table.sequence_values().collect(),
Value::Table(table) => table
.pairs::<T, Value<'lua>>()
.map(|res| res.map(|(k, _)| k))
@ -736,7 +736,7 @@ impl<'lua, T: Ord + FromLua<'lua>> FromLua<'lua> for BTreeSet<T> {
#[inline]
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
match value {
Value::Table(table) if table.len()? > 0 => table.sequence_values().collect(),
Value::Table(table) if table.raw_len() > 0 => table.sequence_values().collect(),
Value::Table(table) => table
.pairs::<T, Value<'lua>>()
.map(|res| res.map(|(k, _)| k))

View File

@ -237,7 +237,7 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
let len = t.raw_len() as usize;
let mut deserializer = SeqDeserializer {
seq: t.raw_sequence_values(),
seq: t.sequence_values(),
options: self.options,
visited: self.visited,
};

View File

@ -641,12 +641,9 @@ impl<'lua> Table<'lua> {
/// Consume this table and return an iterator over all values in the sequence part of the table.
///
/// The iterator will yield all values `t[1]`, `t[2]`, and so on, until a `nil` value is
/// encountered. This mirrors the behavior of Lua's `ipairs` function and will invoke the
/// `__index` metamethod according to the usual rules. However, the deprecated `__ipairs`
/// metatable will not be called.
///
/// Just like [`pairs`], the values are wrapped in a [`Result`].
/// The iterator will yield all values `t[1]`, `t[2]` and so on, until a `nil` value is
/// encountered. This mirrors the behavior of Lua's `ipairs` function but does not invoke
/// any metamethods.
///
/// # Note
///
@ -685,28 +682,12 @@ impl<'lua> Table<'lua> {
table: self.0,
index: Some(1),
len: None,
raw: false,
_phantom: PhantomData,
}
}
/// Consume this table and return an iterator over all values in the sequence part of the table.
///
/// Unlike the `sequence_values`, does not invoke `__index` metamethod when iterating.
///
/// [`sequence_values`]: #method.sequence_values
pub fn raw_sequence_values<V: FromLua<'lua>>(self) -> TableSequence<'lua, V> {
TableSequence {
table: self.0,
index: Some(1),
len: None,
raw: true,
_phantom: PhantomData,
}
}
#[cfg(feature = "serialize")]
pub(crate) fn raw_sequence_values_by_len<V: FromLua<'lua>>(
pub(crate) fn sequence_values_by_len<V: FromLua<'lua>>(
self,
len: Option<Integer>,
) -> TableSequence<'lua, V> {
@ -715,7 +696,6 @@ impl<'lua> Table<'lua> {
table: self.0,
index: Some(1),
len: Some(len),
raw: true,
_phantom: PhantomData,
}
}
@ -1051,7 +1031,7 @@ impl<'lua> Serialize for Table<'lua> {
let len = self.raw_len() as usize;
if len > 0 || self.is_array() {
let mut seq = serializer.serialize_seq(Some(len))?;
for v in self.clone().raw_sequence_values_by_len::<Value>(None) {
for v in self.clone().sequence_values_by_len::<Value>(None) {
let v = v.map_err(serde::ser::Error::custom)?;
seq.serialize_element(&v)?;
}
@ -1141,7 +1121,6 @@ pub struct TableSequence<'lua, V> {
table: LuaRef<'lua>,
index: Option<Integer>,
len: Option<Integer>,
raw: bool,
_phantom: PhantomData<V>,
}
@ -1158,15 +1137,10 @@ where
let res = (|| unsafe {
let _sg = StackGuard::new(state);
check_stack(state, 1 + if self.raw { 0 } else { 3 })?;
check_stack(state, 1)?;
lua.push_ref(&self.table);
let res = if self.raw {
ffi::lua_rawgeti(state, -1, index)
} else {
protect_lua!(state, 1, 1, |state| ffi::lua_geti(state, -1, index))?
};
match res {
match ffi::lua_rawgeti(state, -1, index) {
ffi::LUA_TNIL if index > self.len.unwrap_or(0) => Ok(None),
_ => Ok(Some((index, lua.pop_value()))),
}

View File

@ -141,7 +141,7 @@ fn test_table_push_pop() -> Result<()> {
assert_eq!(
table2
.clone()
.raw_sequence_values::<i64>()
.sequence_values::<i64>()
.collect::<Result<Vec<_>>>()?,
vec![]
);