@@ -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 < 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+ self . globals ( )
44+ . raw_set ( "require" , self . create_require ( require:: TextRequirer :: new ( ) ) ?) ?;
2945
3046 Ok ( ( ) )
3147 }
0 commit comments