pub use luaify::*; use rustc_hash::FxHasher; use std::{ any::TypeId, fmt::{self, Display, Formatter}, hash::{Hash, Hasher}, }; #[allow(non_camel_case_types)] pub mod stub_types { pub struct any; pub struct many; pub struct nil; pub type boolean = bool; pub struct lightuserdata; pub struct number; pub struct integer; pub type string = String; pub struct table; pub struct function; pub struct userdata; pub struct thread; pub struct cdata; pub struct variadic; } pub fn type_id() -> u64 { let mut hash = FxHasher::default(); TypeId::of::().hash(&mut hash); hash.finish() } macro_rules! export { ($($fn:expr),+ $(,)?) => { // this ensures ffi function symbol exports are actually present in the resulting binary, // otherwise they may get dead code-eliminated before it reaches the linker #[used] static __FFI_EXPORTS: &[fn()] = unsafe { &[$(::std::mem::transmute($fn as *const ())),*] }; }; } macro_rules! display { ($($fmt:expr),+) => {{ crate::__internal::disp(move |f| write!(f, $($fmt),+)) }}; } pub(crate) use {display, export}; pub fn disp(f: impl Fn(&mut Formatter) -> fmt::Result) -> impl Display { struct Disp fmt::Result>(F); impl fmt::Result> Display for Disp { fn fmt(&self, f: &mut Formatter) -> fmt::Result { (self.0)(f) } } Disp(f) } pub fn write_sep( f: &mut Formatter, sep: impl Display, iter: impl IntoIterator, ) -> fmt::Result { for (i, s) in iter.into_iter().enumerate() { if i != 0 { write!(f, "{sep}")?; } write!(f, "{s}")?; } Ok(()) }