Skip to main content

mlua/
types.rs

1use std::cell::UnsafeCell;
2use std::os::raw::{c_int, c_void};
3
4#[cfg(not(feature = "luau"))]
5use crate::debug::{Debug, HookTriggers};
6use crate::error::Result;
7use crate::state::{ExtraData, Lua, RawLua};
8
9// Re-export mutex wrappers
10pub(crate) use sync::{ArcReentrantMutexGuard, ReentrantMutex, ReentrantMutexGuard, XRc, XWeak};
11
12#[cfg(all(feature = "async", feature = "send"))]
13pub(crate) type BoxFuture<'a, T> = futures_util::future::BoxFuture<'a, T>;
14
15#[cfg(all(feature = "async", not(feature = "send")))]
16pub(crate) type BoxFuture<'a, T> = futures_util::future::LocalBoxFuture<'a, T>;
17
18pub use app_data::{AppData, AppDataRef, AppDataRefMut};
19pub use either::Either;
20pub use registry_key::RegistryKey;
21pub(crate) use value_ref::ValueRef;
22
23/// Type of Lua integer numbers.
24pub type Integer = ffi::lua_Integer;
25/// Type of Lua floating point numbers.
26pub type Number = ffi::lua_Number;
27
28/// A "light" userdata value. Equivalent to an unmanaged raw pointer.
29#[derive(Debug, Copy, Clone, Eq, PartialEq)]
30pub struct LightUserData(pub *mut c_void);
31
32#[cfg(feature = "send")]
33unsafe impl Send for LightUserData {}
34#[cfg(feature = "send")]
35unsafe impl Sync for LightUserData {}
36
37#[cfg(feature = "send")]
38type CallbackFn<'a> = dyn Fn(&RawLua, c_int) -> Result<c_int> + Send + 'a;
39
40#[cfg(not(feature = "send"))]
41type CallbackFn<'a> = dyn Fn(&RawLua, c_int) -> Result<c_int> + 'a;
42
43pub(crate) type Callback = Box<CallbackFn<'static>>;
44pub(crate) type CallbackPtr = *const CallbackFn<'static>;
45
46pub(crate) type ScopedCallback<'s> = Box<dyn Fn(&RawLua, c_int) -> Result<c_int> + 's>;
47
48pub(crate) struct Upvalue<T> {
49    pub(crate) data: T,
50    pub(crate) extra: XRc<UnsafeCell<ExtraData>>,
51}
52
53pub(crate) type CallbackUpvalue = Upvalue<Option<Callback>>;
54
55#[cfg(all(feature = "async", feature = "send"))]
56pub(crate) type AsyncCallback =
57    Box<dyn for<'a> Fn(&'a RawLua, c_int) -> BoxFuture<'a, Result<c_int>> + Send + 'static>;
58
59#[cfg(all(feature = "async", not(feature = "send")))]
60pub(crate) type AsyncCallback =
61    Box<dyn for<'a> Fn(&'a RawLua, c_int) -> BoxFuture<'a, Result<c_int>> + 'static>;
62
63#[cfg(feature = "async")]
64pub(crate) type AsyncCallbackUpvalue = Upvalue<AsyncCallback>;
65
66#[cfg(feature = "async")]
67pub(crate) type AsyncPollUpvalue = Upvalue<Option<BoxFuture<'static, Result<c_int>>>>;
68
69/// Type to set next Lua VM action after executing interrupt or hook function.
70#[non_exhaustive]
71pub enum VmState {
72    Continue,
73    /// Yield the current thread.
74    ///
75    /// Supported by Lua 5.3+ and Luau.
76    Yield,
77}
78
79#[cfg(not(feature = "luau"))]
80pub(crate) enum HookKind {
81    Global,
82    Thread(HookTriggers, HookCallback),
83}
84
85#[cfg(all(feature = "send", not(feature = "luau")))]
86pub(crate) type HookCallback = XRc<dyn Fn(&Lua, &Debug) -> Result<VmState> + Send>;
87
88#[cfg(all(not(feature = "send"), not(feature = "luau")))]
89pub(crate) type HookCallback = XRc<dyn Fn(&Lua, &Debug) -> Result<VmState>>;
90
91#[cfg(all(feature = "send", feature = "luau"))]
92pub(crate) type InterruptCallback = XRc<dyn Fn(&Lua) -> Result<VmState> + Send>;
93
94#[cfg(all(not(feature = "send"), feature = "luau"))]
95pub(crate) type InterruptCallback = XRc<dyn Fn(&Lua) -> Result<VmState>>;
96
97#[cfg(feature = "send")]
98pub(crate) type ThreadEventCallback = XRc<dyn Fn(&Lua, crate::thread::ThreadEvent) -> Result<()> + Send>;
99
100#[cfg(not(feature = "send"))]
101pub(crate) type ThreadEventCallback = XRc<dyn Fn(&Lua, crate::thread::ThreadEvent) -> Result<()>>;
102
103#[cfg(feature = "send")]
104#[cfg(any(feature = "lua55", feature = "lua54"))]
105pub(crate) type WarnCallback = XRc<dyn Fn(&Lua, &str, bool) -> Result<()> + Send>;
106
107#[cfg(not(feature = "send"))]
108#[cfg(any(feature = "lua55", feature = "lua54"))]
109pub(crate) type WarnCallback = XRc<dyn Fn(&Lua, &str, bool) -> Result<()>>;
110
111/// A trait that adds `Send` requirement if `send` feature is enabled.
112#[cfg(feature = "send")]
113pub trait MaybeSend: Send {}
114#[cfg(feature = "send")]
115impl<T: Send> MaybeSend for T {}
116
117/// A trait that adds `Send` requirement if `send` feature is enabled.
118#[cfg(not(feature = "send"))]
119pub trait MaybeSend {}
120#[cfg(not(feature = "send"))]
121impl<T> MaybeSend for T {}
122
123/// Adds a `Sync` requirement to userdata types when the `send` feature is enabled.
124///
125/// It is automatically implemented for all applicable types.
126#[cfg(feature = "send")]
127pub trait MaybeSync: Sync {}
128#[cfg(feature = "send")]
129impl<T: Sync> MaybeSync for T {}
130
131/// Adds a `Sync` requirement to userdata types when the `send` feature is enabled.
132///
133/// It is automatically implemented for all applicable types.
134#[cfg(not(feature = "send"))]
135pub trait MaybeSync {}
136#[cfg(not(feature = "send"))]
137impl<T> MaybeSync for T {}
138
139pub(crate) struct DestructedUserdata;
140
141pub(crate) trait LuaType {
142    const TYPE_ID: c_int;
143}
144
145impl LuaType for bool {
146    const TYPE_ID: c_int = ffi::LUA_TBOOLEAN;
147}
148
149impl LuaType for Number {
150    const TYPE_ID: c_int = ffi::LUA_TNUMBER;
151}
152
153impl LuaType for LightUserData {
154    const TYPE_ID: c_int = ffi::LUA_TLIGHTUSERDATA;
155}
156
157mod app_data;
158mod registry_key;
159mod sync;
160mod value_ref;
161
162#[cfg(test)]
163mod assertions {
164    use super::*;
165
166    #[cfg(not(feature = "send"))]
167    static_assertions::assert_not_impl_any!(ValueRef: Send);
168    #[cfg(feature = "send")]
169    static_assertions::assert_impl_all!(ValueRef: Send, Sync);
170}