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:
parent
399e469328
commit
b169031d4e
|
@ -709,7 +709,7 @@ impl<'lua, T: Eq + Hash + FromLua<'lua>, S: BuildHasher + Default> FromLua<'lua>
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
||||||
match value {
|
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
|
Value::Table(table) => table
|
||||||
.pairs::<T, Value<'lua>>()
|
.pairs::<T, Value<'lua>>()
|
||||||
.map(|res| res.map(|(k, _)| k))
|
.map(|res| res.map(|(k, _)| k))
|
||||||
|
@ -736,7 +736,7 @@ impl<'lua, T: Ord + FromLua<'lua>> FromLua<'lua> for BTreeSet<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
||||||
match value {
|
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
|
Value::Table(table) => table
|
||||||
.pairs::<T, Value<'lua>>()
|
.pairs::<T, Value<'lua>>()
|
||||||
.map(|res| res.map(|(k, _)| k))
|
.map(|res| res.map(|(k, _)| k))
|
||||||
|
|
|
@ -237,7 +237,7 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
|
||||||
|
|
||||||
let len = t.raw_len() as usize;
|
let len = t.raw_len() as usize;
|
||||||
let mut deserializer = SeqDeserializer {
|
let mut deserializer = SeqDeserializer {
|
||||||
seq: t.raw_sequence_values(),
|
seq: t.sequence_values(),
|
||||||
options: self.options,
|
options: self.options,
|
||||||
visited: self.visited,
|
visited: self.visited,
|
||||||
};
|
};
|
||||||
|
|
40
src/table.rs
40
src/table.rs
|
@ -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.
|
/// 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
|
/// 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
|
/// encountered. This mirrors the behavior of Lua's `ipairs` function but does not invoke
|
||||||
/// `__index` metamethod according to the usual rules. However, the deprecated `__ipairs`
|
/// any metamethods.
|
||||||
/// metatable will not be called.
|
|
||||||
///
|
|
||||||
/// Just like [`pairs`], the values are wrapped in a [`Result`].
|
|
||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
///
|
///
|
||||||
|
@ -685,28 +682,12 @@ impl<'lua> Table<'lua> {
|
||||||
table: self.0,
|
table: self.0,
|
||||||
index: Some(1),
|
index: Some(1),
|
||||||
len: None,
|
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,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[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,
|
self,
|
||||||
len: Option<Integer>,
|
len: Option<Integer>,
|
||||||
) -> TableSequence<'lua, V> {
|
) -> TableSequence<'lua, V> {
|
||||||
|
@ -715,7 +696,6 @@ impl<'lua> Table<'lua> {
|
||||||
table: self.0,
|
table: self.0,
|
||||||
index: Some(1),
|
index: Some(1),
|
||||||
len: Some(len),
|
len: Some(len),
|
||||||
raw: true,
|
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1031,7 @@ impl<'lua> Serialize for Table<'lua> {
|
||||||
let len = self.raw_len() as usize;
|
let len = self.raw_len() as usize;
|
||||||
if len > 0 || self.is_array() {
|
if len > 0 || self.is_array() {
|
||||||
let mut seq = serializer.serialize_seq(Some(len))?;
|
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)?;
|
let v = v.map_err(serde::ser::Error::custom)?;
|
||||||
seq.serialize_element(&v)?;
|
seq.serialize_element(&v)?;
|
||||||
}
|
}
|
||||||
|
@ -1141,7 +1121,6 @@ pub struct TableSequence<'lua, V> {
|
||||||
table: LuaRef<'lua>,
|
table: LuaRef<'lua>,
|
||||||
index: Option<Integer>,
|
index: Option<Integer>,
|
||||||
len: Option<Integer>,
|
len: Option<Integer>,
|
||||||
raw: bool,
|
|
||||||
_phantom: PhantomData<V>,
|
_phantom: PhantomData<V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,15 +1137,10 @@ where
|
||||||
|
|
||||||
let res = (|| unsafe {
|
let res = (|| unsafe {
|
||||||
let _sg = StackGuard::new(state);
|
let _sg = StackGuard::new(state);
|
||||||
check_stack(state, 1 + if self.raw { 0 } else { 3 })?;
|
check_stack(state, 1)?;
|
||||||
|
|
||||||
lua.push_ref(&self.table);
|
lua.push_ref(&self.table);
|
||||||
let res = if self.raw {
|
match ffi::lua_rawgeti(state, -1, index) {
|
||||||
ffi::lua_rawgeti(state, -1, index)
|
|
||||||
} else {
|
|
||||||
protect_lua!(state, 1, 1, |state| ffi::lua_geti(state, -1, index))?
|
|
||||||
};
|
|
||||||
match res {
|
|
||||||
ffi::LUA_TNIL if index > self.len.unwrap_or(0) => Ok(None),
|
ffi::LUA_TNIL if index > self.len.unwrap_or(0) => Ok(None),
|
||||||
_ => Ok(Some((index, lua.pop_value()))),
|
_ => Ok(Some((index, lua.pop_value()))),
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn test_table_push_pop() -> Result<()> {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table2
|
table2
|
||||||
.clone()
|
.clone()
|
||||||
.raw_sequence_values::<i64>()
|
.sequence_values::<i64>()
|
||||||
.collect::<Result<Vec<_>>>()?,
|
.collect::<Result<Vec<_>>>()?,
|
||||||
vec![]
|
vec![]
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue