@@ -2,14 +2,33 @@ use std::ffi::CStr;
22use std::os::raw::c_int;
33
44use crate::error::Result;
5- use crate::state::{ExtraData, Lua, LuaOptions};
5+ use crate::function::Function;
6+ use crate::state::Lua;
67
78pub use require::{NavigateError, Require};
89
910// Since Luau has some missing standard functions, we re-implement them here
1011
1112impl Lua {
12- pub(crate) unsafe fn configure_luau(&self, mut options: LuaOptions) -> Result<()> {
13+ /// Create a custom Luau `require` function using provided [`Require`] implementation to find
14+ /// and load modules.
15+ ///
16+ /// The provided object is stored in the Lua registry and will not be garbage collected
17+ /// until the Lua state is closed.
18+ #[cfg(any(feature = "luau", doc))]
19+ #[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
20+ pub fn create_require_function<R: Require + 'static>(&self, require: R) -> Result<Function> {
21+ unsafe {
22+ self.exec_raw((), move |state| {
23+ let requirer_ptr = ffi::lua_newuserdata_t::<Box<dyn Require>>(state, Box::new(require));
24+ // Keep the require object in the registry to prevent it from being garbage collected
25+ ffi::lua_rawsetp(state, ffi::LUA_REGISTRYINDEX, requirer_ptr as *const _);
26+ ffi::lua_pushrequire(state, require::init_config, requirer_ptr as *mut _);
27+ })
28+ }
29+ }
30+
31+ pub(crate) unsafe fn configure_luau(&self) -> Result<()> {
1332 let globals = self.globals();
1433
1534 globals.raw_set("collectgarbage", self.create_c_function(lua_collectgarbage)?)?;
@@ -20,12 +39,9 @@ impl Lua {
2039 globals.raw_set("_VERSION", format!("Luau {version}"))?;
2140 }
2241
23- // Enable `require` function
24- let requirer = (options.requirer.take()).unwrap_or_else(|| Box::new(require::TextRequirer::new()));
25- self.exec_raw::<()>((), |state| {
26- let requirer_ptr = (*ExtraData::get(state)).set_requirer(requirer);
27- ffi::luaopen_require(state, require::init_config, requirer_ptr as *mut _);
28- })?;
42+ // Enable default `require` implementation
43+ let require = self.create_require_function(require::TextRequirer::new())?;
44+ self.globals().raw_set("require", require)?;
2945
3046 Ok(())
3147 }
0 commit comments