use super::*;
use crate::{ffi::*, FromLua, State, ToLua, Type, ValRef};
use ::serde::{
de::{
Deserialize, DeserializeSeed, Deserializer, Error as DeErr, MapAccess, SeqAccess, Visitor,
},
ser::{
Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, Serializer,
},
};
use alloc::fmt::{self, Display};
#[derive(Clone, Debug, PartialEq, Display)]
pub enum DesErr {
Message(String),
Eof,
Syntax,
ExpectedBoolean,
ExpectedInteger,
ExpectedString,
ExpectedNull,
ExpectedArray,
ExpectedArrayComma,
ExpectedArrayEnd,
ExpectedMap,
ExpectedMapColon,
ExpectedMapComma,
ExpectedMapEnd,
ExpectedEnum,
TrailingCharacters,
}
#[cfg(feature = "std")]
impl std::error::Error for DesErr {}
impl DeErr for DesErr {
fn custom<T: Display>(msg: T) -> Self {
DesErr::Message(msg.to_string())
}
}
impl State {
#[inline(always)]
pub fn push_serialize<V: Serialize>(&self, v: V) -> Result<(), core::fmt::Error> {
v.serialize(LuaSerializer(self))
}
}
#[derive(Copy, Clone, Deref, DerefMut)]
pub struct SerdeValue<T>(pub T);
impl<T: Serialize> ToLua for SerdeValue<T> {
#[inline(always)]
fn to_lua(self, s: &State) {
if let Err(err) = s.push_serialize(self.0) {
s.raise_error(err);
}
}
}
impl<'a, T: Deserialize<'a>> FromLua for SerdeValue<T> {
#[inline(always)]
fn from_lua(s: &State, i: i32) -> Option<SerdeValue<T>> {
Some(SerdeValue(T::deserialize(s.val(i)).ok()?))
}
}
impl ValRef<'_> {
#[inline(always)]
pub fn deserialize<'a, T: Deserialize<'a>>(&self) -> Result<T, DesErr> {
T::deserialize(*self)
}
}
struct LuaSerializer<'a>(&'a State);
struct LuaTableSerializer<'a>(&'a State, i64);
impl SerializeSeq for LuaTableSerializer<'_> {
type Ok = ();
type Error = core::fmt::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
self.1 += 1;
self.0.push_serialize(value)?;
self.0.raw_seti(-2, self.1);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(())
}
}
impl SerializeTuple for LuaTableSerializer<'_> {
type Ok = ();
type Error = core::fmt::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
SerializeSeq::end(self)
}
}
impl SerializeTupleStruct for LuaTableSerializer<'_> {
type Ok = ();
type Error = core::fmt::Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
SerializeSeq::end(self)
}
}
impl SerializeTupleVariant for LuaTableSerializer<'_> {
type Ok = ();
type Error = core::fmt::Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
SerializeTupleStruct::serialize_field(self, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
SerializeTupleStruct::end(self)
}
}
impl<'a> LuaTableSerializer<'a> {
fn begin(s: &'a State, len: usize) -> Self {
s.create_table(0, len as _);
Self(s, 0)
}
fn begin_array(s: &'a State, len: usize) -> Self {
s.create_table(len as _, 0);
Self(s, 0)
}
}
impl SerializeStruct for LuaTableSerializer<'_> {
type Ok = ();
type Error = core::fmt::Error;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
self.0.push(key);
SerializeMap::serialize_value(self, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
SerializeMap::end(self)
}
}
impl SerializeMap for LuaTableSerializer<'_> {
type Ok = ();
type Error = core::fmt::Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
self.0.push_serialize(key)
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
self.0.push_serialize(value)?;
self.0.raw_set(-3);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(())
}
}
impl SerializeStructVariant for LuaTableSerializer<'_> {
type Ok = ();
type Error = core::fmt::Error;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
SerializeStruct::serialize_field(self, key, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
SerializeStruct::end(self)
}
}
impl<'a> Serializer for LuaSerializer<'a> {
type Ok = ();
type Error = core::fmt::Error;
type SerializeSeq = LuaTableSerializer<'a>;
type SerializeMap = LuaTableSerializer<'a>;
type SerializeTuple = LuaTableSerializer<'a>;
type SerializeStruct = LuaTableSerializer<'a>;
type SerializeStructVariant = LuaTableSerializer<'a>;
type SerializeTupleStruct = LuaTableSerializer<'a>;
type SerializeTupleVariant = LuaTableSerializer<'a>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
let mut dst = [0u8; 100];
self.0.push(v.encode_utf8(&mut dst).as_bytes());
Ok(())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
self.0.push(v);
Ok(())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
self.0.push_nil();
Ok(())
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
self.0.push_serialize(value)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
self.0.push_nil();
Ok(())
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
let mut s = LuaTableSerializer::begin(self.0, 1);
SerializeStruct::serialize_field(&mut s, "__unit_struct", name)?;
SerializeStruct::end(s)
}
fn serialize_unit_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
let mut s = LuaTableSerializer::begin(self.0, 1);
s.serialize_entry(&0, &variant_index);
s.serialize_entry(variant, &true);
SerializeMap::end(s)
}
fn serialize_newtype_struct<T: ?Sized>(
self,
name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
self.0.push_serialize(value)
}
fn serialize_newtype_variant<T: ?Sized>(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
let mut s = LuaTableSerializer::begin(self.0, 1);
s.serialize_entry(&0, &variant_index);
s.serialize_entry("__tag", variant);
s.serialize_entry(variant, value);
SerializeMap::end(s)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Ok(LuaTableSerializer::begin_array(self.0, len.unwrap_or(0)))
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Ok(LuaTableSerializer::begin_array(self.0, len))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Ok(LuaTableSerializer::begin_array(self.0, len))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
let mut s = LuaTableSerializer::begin_array(self.0, len);
s.serialize_entry(&0, &variant_index);
s.serialize_entry("__tag", variant);
Ok(s)
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Ok(LuaTableSerializer::begin(self.0, len.unwrap_or(0)))
}
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Ok(LuaTableSerializer::begin(self.0, len))
}
fn serialize_struct_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
let mut s = LuaTableSerializer::begin(self.0, 1);
s.serialize_entry(&0, &variant_index);
s.serialize_entry("__tag", variant);
Ok(s)
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
Err(core::fmt::Error)
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
Err(core::fmt::Error)
}
}
impl<'de> Deserializer<'de> for ValRef<'_> {
type Error = DesErr;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.state.type_of(self.index) {
Type::Number => {
if self.state.is_integer(self.index) {
visitor.visit_i64(self.state.to_integer(self.index))
} else {
visitor.visit_f64(self.state.to_number(self.index))
}
}
Type::String => self.deserialize_str(visitor),
Type::Boolean => self.deserialize_bool(visitor),
Type::Table => {
if self.state.raw_len(self.index) > 0 {
self.deserialize_seq(visitor)
} else {
self.deserialize_map(visitor)
}
}
_ => visitor.visit_unit(),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_bool(self.state.to_bool(self.index))
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i8(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i16(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i32(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i64(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u8(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u16(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u32(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u64(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_f32(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_f64(self.state.arg(self.index).ok_or(DesErr::ExpectedInteger)?)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.state.type_of(self.index) {
Type::Number => visitor.visit_char(self.state.to_integer(self.index) as u8 as _),
Type::String => {
let s = self.state.to_str(self.index).unwrap();
visitor.visit_char(
s.chars()
.next()
.ok_or(DesErr::Message("empty char".into()))?,
)
}
_ => Err(DesErr::Message("invalid char type".into())),
}
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_borrowed_str(
self.state
.to_str(self.index)
.ok_or(DesErr::ExpectedString)?,
)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_borrowed_bytes(
self.state
.to_bytes(self.index)
.ok_or(DesErr::ExpectedString)?,
)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if self.state.is_none_or_nil(self.index) {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if self.state.is_none_or_nil(self.index) {
visitor.visit_unit()
} else {
Err(DesErr::ExpectedNull)
}
}
fn deserialize_unit_struct<V>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
struct SeqDes<'a>(ValRef<'a>, usize, usize);
impl<'de> SeqAccess<'de> for SeqDes<'_> {
type Error = DesErr;
#[inline]
fn size_hint(&self) -> Option<usize> {
Some(self.0.state.raw_len(self.0.index))
}
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
if self.1 > self.2 {
return Ok(None);
}
self.0.state.raw_geti(self.0.index, self.1 as _);
self.1 += 1;
let r = seed.deserialize(self.0.state.val(-1))?;
self.0.state.pop(1);
Ok(Some(r))
}
}
if self.state.is_table(self.index) {
visitor.visit_seq(SeqDes(self, 1, self.state.raw_len(self.index)))
} else {
Err(DesErr::ExpectedArray)
}
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
impl<'de> MapAccess<'de> for ValRef<'_> {
type Error = DesErr;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
if self.state.next(self.index) {
Ok(Some(seed.deserialize(self.state.val(-2))?))
} else {
Ok(None)
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: DeserializeSeed<'de>,
{
let r = seed.deserialize(self.state.val(-1))?;
self.state.pop(1);
Ok(r)
}
}
if self.state.is_table(self.index) {
self.state.push_nil();
visitor.visit_map(self)
} else {
Err(DesErr::ExpectedMap)
}
}
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_map(visitor)
}
fn deserialize_enum<V>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
}
struct DeLua<'a>(&'a State);
impl<'de> DeserializeSeed<'de> for DeLua<'_> {
type Value = ();
fn deserialize<D>(self, deserializer: D) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(LuaVisitor(self.0))?;
Ok(())
}
}
pub struct LuaVisitor<'a>(pub &'a State);
impl<'de> Visitor<'de> for LuaVisitor<'_> {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("lua visitor")
}
fn visit_bool<E: DeErr>(self, v: bool) -> Result<Self::Value, E> {
self.0.push(v);
Ok(())
}
fn visit_i64<E: DeErr>(self, v: i64) -> Result<Self::Value, E> {
self.0.push(v);
Ok(())
}
fn visit_f64<E: DeErr>(self, v: f64) -> Result<Self::Value, E> {
self.0.push(v);
Ok(())
}
fn visit_u64<E: DeErr>(self, v: u64) -> Result<Self::Value, E> {
self.0.push(v);
Ok(())
}
fn visit_bytes<E: DeErr>(self, v: &[u8]) -> Result<Self::Value, E> {
self.0.push(v);
Ok(())
}
fn visit_str<E: DeErr>(self, v: &str) -> Result<Self::Value, E> {
self.0.push(v);
Ok(())
}
fn visit_none<E: DeErr>(self) -> Result<Self::Value, E> {
self.0.push_nil();
Ok(())
}
fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
deserializer.deserialize_any(LuaVisitor(self.0))
}
fn visit_unit<E: DeErr>(self) -> Result<Self::Value, E> {
self.0.push_nil();
Ok(())
}
fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
where
A: SeqAccess<'de>,
{
let size = seq.size_hint();
self.0.create_table(size.unwrap_or_default() as _, 0);
if let Some(size) = size {
for i in 1..=size {
match seq.next_element_seed(DeLua(self.0))? {
Some(_) => self.0.raw_seti(-2, i as lua_Integer),
None => continue,
}
}
} else {
let mut i = 0;
while let Some(_) = seq.next_element_seed(DeLua(self.0))? {
i += 1;
self.0.raw_seti(-2, i);
}
}
Ok(())
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let size = map.size_hint();
self.0.create_table(0, size.unwrap_or_default() as _);
if let Some(size) = size {
for _ in 1..=size {
match map.next_key_seed(DeLua(self.0))? {
Some(_) => {
map.next_value_seed(DeLua(self.0))?;
self.0.raw_set(-3);
}
None => continue,
}
}
} else {
while let Some(_) = map.next_key_seed(DeLua(self.0))? {
map.next_value_seed(DeLua(self.0))?;
self.0.raw_set(-3);
}
}
Ok(())
}
}
impl Serialize for ValRef<'_> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
unsafe {
match lua_type(self.state.as_ptr(), self.index) {
LUA_TSTRING => {
let bytes = self.state.to_bytes(self.index).unwrap_or_default();
if bytes.len() > 300 {
serializer.serialize_bytes(bytes)
} else {
match std::str::from_utf8(bytes) {
Ok(s) => serializer.serialize_str(s),
Err(_) => serializer.serialize_bytes(bytes),
}
}
}
LUA_TNUMBER => {
if self.is_integer() {
serializer.serialize_i64(self.state.to_integer(self.index))
} else {
serializer.serialize_f64(self.state.to_number(self.index))
}
}
LUA_TFUNCTION => serializer.serialize_bool(true),
LUA_TBOOLEAN => serializer.serialize_bool(self.to_bool()),
LUA_TTABLE => {
if self.state.raw_len(self.index) > 0 {
let len = self.state.raw_len(self.index) as usize;
let mut seq = serializer.serialize_seq(Some(len))?;
for i in 1..=len {
self.state.raw_geti(self.index, i as lua_Integer);
seq.serialize_element(&self.state.val(-1))?;
self.state.pop(1);
}
seq.end()
} else {
let mut count = 0usize;
self.state.push_nil();
while lua_next(self.state.as_ptr(), self.index) != 0 {
count += 1;
self.state.pop(1);
}
let mut map = serializer.serialize_map(Some(count))?;
self.state.push_nil();
while lua_next(self.state.as_ptr(), self.index) != 0 {
if let Err(_) =
map.serialize_entry(&self.state.val(-2), &self.state.val(-1))
{
}
self.state.pop(1);
}
map.end()
}
}
_ => serializer.serialize_none(),
}
}
}
}