@@ -15,6 +15,7 @@ use crate::table::Table;
1515use crate :: types:: MaybeSend ;
1616
1717/// An error that can occur during navigation in the Luau `require` system.
18+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
1819pub enum NavigateError {
1920 Ambiguous ,
2021 NotFound ,
@@ -91,7 +92,7 @@ impl fmt::Debug for dyn Require {
9192}
9293
9394/// The standard implementation of Luau `require` navigation.
94- #[ derive( Default ) ]
95+ #[ derive( Default , Debug ) ]
9596pub ( super ) struct TextRequirer {
9697 abs_path : PathBuf ,
9798 rel_path : PathBuf ,
@@ -141,35 +142,25 @@ impl TextRequirer {
141142 components. into_iter ( ) . collect ( )
142143 }
143144
144- fn find_module_path ( path : & Path ) -> StdResult < PathBuf , NavigateError > {
145+ fn find_module ( path : & Path ) -> StdResult < PathBuf , NavigateError > {
145146 let mut found_path = None ;
146147
147- if path. components ( ) . last ( ) != Some ( Component :: Normal ( "init" . as_ref ( ) ) ) {
148+ if path. components ( ) . next_back ( ) != Some ( Component :: Normal ( "init" . as_ref ( ) ) ) {
148149 let current_ext = ( path. extension ( ) . and_then ( |s| s. to_str ( ) ) )
149150 . map ( |s| format ! ( "{s}." ) )
150151 . unwrap_or_default ( ) ;
151152 for ext in [ "luau" , "lua" ] {
152153 let candidate = path. with_extension ( format ! ( "{current_ext}{ext}" ) ) ;
153- if candidate. is_file ( ) {
154- if found_path. is_some ( ) {
155- return Err ( NavigateError :: Ambiguous ) ;
156- }
157- found_path = Some ( candidate) ;
154+ if candidate. is_file ( ) && found_path. replace ( candidate) . is_some ( ) {
155+ return Err ( NavigateError :: Ambiguous ) ;
158156 }
159157 }
160158 }
161159 if path. is_dir ( ) {
162- if found_path. is_some ( ) {
163- return Err ( NavigateError :: Ambiguous ) ;
164- }
165-
166160 for component in [ "init.luau" , "init.lua" ] {
167161 let candidate = path. join ( component) ;
168- if candidate. is_file ( ) {
169- if found_path. is_some ( ) {
170- return Err ( NavigateError :: Ambiguous ) ;
171- }
172- found_path = Some ( candidate) ;
162+ if candidate. is_file ( ) && found_path. replace ( candidate) . is_some ( ) {
163+ return Err ( NavigateError :: Ambiguous ) ;
173164 }
174165 }
175166
@@ -191,36 +182,30 @@ impl Require for TextRequirer {
191182 if !chunk_name. starts_with ( '@' ) {
192183 return Err ( NavigateError :: NotFound ) ;
193184 }
194- let chunk_name = & Self :: normalize_chunk_name ( chunk_name) [ 1 ..] ;
195- let path = Self :: normalize_path ( chunk_name. as_ref ( ) ) ;
196-
197- if path. extension ( ) == Some ( "rs" . as_ref ( ) ) {
198- let cwd = match env:: current_dir ( ) {
199- Ok ( cwd) => cwd,
200- Err ( _) => return Err ( NavigateError :: NotFound ) ,
201- } ;
202- self . abs_path = Self :: normalize_path ( & cwd. join ( & path) ) ;
203- self . rel_path = path;
185+ let chunk_name = Self :: normalize_chunk_name ( & chunk_name[ 1 ..] ) ;
186+ let chunk_path = Self :: normalize_path ( chunk_name. as_ref ( ) ) ;
187+
188+ if chunk_path. extension ( ) == Some ( "rs" . as_ref ( ) ) {
189+ let cwd = env:: current_dir ( ) . map_err ( |_| NavigateError :: NotFound ) ?;
190+ self . abs_path = Self :: normalize_path ( & cwd. join ( & chunk_path) ) ;
191+ self . rel_path = chunk_path;
204192 self . module_path = PathBuf :: new ( ) ;
205193
206194 return Ok ( ( ) ) ;
207195 }
208196
209- if path . is_absolute ( ) {
210- let module_path = Self :: find_module_path ( & path ) ?;
211- self . abs_path = path . clone ( ) ;
212- self . rel_path = path ;
197+ if chunk_path . is_absolute ( ) {
198+ let module_path = Self :: find_module ( & chunk_path ) ?;
199+ self . abs_path = chunk_path . clone ( ) ;
200+ self . rel_path = chunk_path ;
213201 self . module_path = module_path;
214202 } else {
215203 // Relative path
216- let cwd = match env:: current_dir ( ) {
217- Ok ( cwd) => cwd,
218- Err ( _) => return Err ( NavigateError :: NotFound ) ,
219- } ;
220- let abs_path = cwd. join ( & path) ;
221- let module_path = Self :: find_module_path ( & abs_path) ?;
222- self . abs_path = Self :: normalize_path ( & abs_path) ;
223- self . rel_path = path;
204+ let cwd = env:: current_dir ( ) . map_err ( |_| NavigateError :: NotFound ) ?;
205+ let abs_path = Self :: normalize_path ( & cwd. join ( & chunk_path) ) ;
206+ let module_path = Self :: find_module ( & abs_path) ?;
207+ self . abs_path = abs_path;
208+ self . rel_path = chunk_path;
224209 self . module_path = module_path;
225210 }
226211
@@ -229,7 +214,7 @@ impl Require for TextRequirer {
229214
230215 fn jump_to_alias ( & mut self , path : & str ) -> StdResult < ( ) , NavigateError > {
231216 let path = Self :: normalize_path ( path. as_ref ( ) ) ;
232- let module_path = Self :: find_module_path ( & path) ?;
217+ let module_path = Self :: find_module ( & path) ?;
233218
234219 self . abs_path = path. clone ( ) ;
235220 self . rel_path = path;
@@ -245,7 +230,7 @@ impl Require for TextRequirer {
245230 }
246231 let mut rel_parent = self . rel_path . clone ( ) ;
247232 rel_parent. pop ( ) ;
248- let module_path = Self :: find_module_path ( & abs_path) ?;
233+ let module_path = Self :: find_module ( & abs_path) ?;
249234
250235 self . abs_path = abs_path;
251236 self . rel_path = Self :: normalize_path ( & rel_parent) ;
@@ -257,7 +242,7 @@ impl Require for TextRequirer {
257242 fn to_child ( & mut self , name : & str ) -> StdResult < ( ) , NavigateError > {
258243 let abs_path = self . abs_path . join ( name) ;
259244 let rel_path = self . rel_path . join ( name) ;
260- let module_path = Self :: find_module_path ( & abs_path) ?;
245+ let module_path = Self :: find_module ( & abs_path) ?;
261246
262247 self . abs_path = abs_path;
263248 self . rel_path = rel_path;
@@ -275,7 +260,7 @@ impl Require for TextRequirer {
275260 }
276261
277262 fn has_config ( & self ) -> bool {
278- self . abs_path . join ( ".luaurc" ) . is_file ( )
263+ self . abs_path . is_dir ( ) && self . abs_path . join ( ".luaurc" ) . is_file ( )
279264 }
280265
281266 fn config ( & self ) -> IoResult < Vec < u8 > > {
@@ -284,9 +269,7 @@ impl Require for TextRequirer {
284269
285270 fn loader ( & self , lua : & Lua ) -> Result < Function > {
286271 let name = format ! ( "@{}" , self . rel_path. display( ) ) ;
287- lua. load ( self . module_path . as_path ( ) )
288- . set_name ( name)
289- . into_function ( )
272+ lua. load ( & * self . module_path ) . set_name ( name) . into_function ( )
290273 }
291274}
292275
0 commit comments