luby/crates/luaffi/src/internal.rs
2025-06-26 19:25:03 +10:00

74 lines
1.8 KiB
Rust

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<T: 'static>() -> u64 {
let mut hash = FxHasher::default();
TypeId::of::<T>().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<F: Fn(&mut Formatter) -> fmt::Result>(F);
impl<F: Fn(&mut Formatter) -> fmt::Result> Display for Disp<F> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
(self.0)(f)
}
}
Disp(f)
}
pub fn write_sep<S: Display>(
f: &mut Formatter,
sep: impl Display,
iter: impl IntoIterator<Item = S>,
) -> fmt::Result {
for (i, s) in iter.into_iter().enumerate() {
if i != 0 {
write!(f, "{sep}")?;
}
write!(f, "{s}")?;
}
Ok(())
}