ezlua 0.5.4

Ergonomic, efficient and Zero-cost rust bindings to Lua5.4
Documentation
#[macro_export]
macro_rules! impL_lua_for_enum {
    ($t:ty($primitive:ty) {
        $(($k:ident = $v:expr),)+
    }) => {
        impl $crate::prelude::ToLua for $t {
            fn to_lua<'a>(
                self,
                lua: &'a $crate::prelude::LuaState,
            ) -> $crate::prelude::LuaResult<$crate::prelude::ValRef<'a>> {
                $crate::prelude::ToLua::to_lua(self as $primitive, lua)
            }
        }

        impl $crate::prelude::FromLua<'_> for $t {
            fn from_lua(
                lua: &$crate::prelude::LuaState,
                val: $crate::prelude::ValRef,
            ) -> $crate::prelude::LuaResult<Self> {
                match <$primitive as $crate::prelude::FromLua>::from_lua(lua, val) {
                    $($v as $primitive => Ok(Self::$k),)+
                    _ => $crate::prelude::LuaResult::Err(::alloc::format!("invalid value for enum {}", stringify!($t))),
                }
            }
        }
    };
}

pub fn close_object(&self) -> Result<()> {
    if let Some(u) = self.as_userdata() {
        let mut i: i32 = 1;
        while u.get_iuservalue(i)?.type_of() != Type::None {
            u.set_iuservalue(i, ())?;
            i += 1;
        }
    } else if let Some(f) = self.as_function() {
        let mut i = 1;
        while let Some(up) = f.get_upvalue(i)? {
            f.set_upvalue(i, ())?;
            up.close_object()?;
            i += 1;
        }
    }
    let _ = self.close_and_remove_metatable();
    Ok(())
}