@@ -159,6 +159,7 @@ impl GlobPart {
159
159
match_partial,
160
160
previous_part_is_path_separator_equivalent,
161
161
cursor : GraphemeCursor :: new ( 0 , path. len ( ) , true ) ,
162
+ index : 0 ,
162
163
glob_iterator : None ,
163
164
}
164
165
}
@@ -257,6 +258,7 @@ struct GlobPartMatchesIterator<'a> {
257
258
match_partial : bool ,
258
259
previous_part_is_path_separator_equivalent : bool ,
259
260
cursor : GraphemeCursor ,
261
+ index : usize ,
260
262
glob_iterator : Option < Box < GlobMatchesIterator < ' a > > > ,
261
263
}
262
264
@@ -267,12 +269,9 @@ impl<'a> Iterator for GlobPartMatchesIterator<'a> {
267
269
match self . part {
268
270
GlobPart :: AnyDirectories => {
269
271
if self . cursor . cur_cursor ( ) == 0 {
270
- let end = self . cursor . next_boundary ( self . path , 0 ) ;
271
- match end {
272
- Ok ( Some ( _) ) => { }
273
- Ok ( None ) => return None ,
274
- Err ( ..) => return None ,
275
- }
272
+ let Ok ( Some ( _) ) = self . cursor . next_boundary ( self . path , 0 ) else {
273
+ return None ;
274
+ } ;
276
275
return Some ( ( self . path , true ) ) ;
277
276
}
278
277
@@ -304,22 +303,19 @@ impl<'a> Iterator for GlobPartMatchesIterator<'a> {
304
303
}
305
304
}
306
305
GlobPart :: AnyFile => {
307
- let end = self . cursor . next_boundary ( self . path , 0 ) ;
308
- match end {
309
- Ok ( Some ( _) ) => { }
310
- Ok ( None ) => return None ,
311
- Err ( ..) => return None ,
312
- }
306
+ let Ok ( Some ( c) ) = self . cursor . next_boundary ( self . path , 0 ) else {
307
+ return None ;
308
+ } ;
313
309
314
- let idx = self . path [ 0 ..self . cursor . cur_cursor ( ) ] . len ( ) ;
310
+ let idx = self . path [ 0 ..c ] . len ( ) ;
315
311
316
312
// TODO verify if `*` does match zero chars?
317
- if let Some ( slice) = self . path . get ( 0 ..self . cursor . cur_cursor ( ) ) {
313
+ if let Some ( slice) = self . path . get ( 0 ..c ) {
318
314
if slice. ends_with ( '/' ) {
319
315
None
320
316
} else {
321
317
Some ( (
322
- & self . path [ self . cursor . cur_cursor ( ) ..] ,
318
+ & self . path [ c ..] ,
323
319
self . previous_part_is_path_separator_equivalent && idx == 1 ,
324
320
) )
325
321
}
@@ -330,14 +326,11 @@ impl<'a> Iterator for GlobPartMatchesIterator<'a> {
330
326
GlobPart :: AnyFileChar => todo ! ( ) ,
331
327
GlobPart :: PathSeparator => {
332
328
if self . cursor . cur_cursor ( ) == 0 {
333
- let end = self . cursor . next_boundary ( self . path , 0 ) ;
334
- match end {
335
- Ok ( Some ( _) ) => { }
336
- Ok ( None ) => return None ,
337
- Err ( ..) => return None ,
338
- }
329
+ let Ok ( Some ( b) ) = self . cursor . next_boundary ( self . path , 0 ) else {
330
+ return None ;
331
+ } ;
339
332
if self . path . starts_with ( '/' ) {
340
- Some ( ( & self . path [ 1 ..] , true ) )
333
+ Some ( ( & self . path [ b ..] , true ) )
341
334
} else if self . previous_part_is_path_separator_equivalent {
342
335
Some ( ( self . path , true ) )
343
336
} else {
@@ -347,28 +340,25 @@ impl<'a> Iterator for GlobPartMatchesIterator<'a> {
347
340
None
348
341
}
349
342
}
350
- GlobPart :: FileChar ( chars) => loop {
351
- let end = match self . cursor . next_boundary ( self . path , 0 ) {
352
- Ok ( Some ( end) ) => end ,
353
- _ => return None ,
343
+ GlobPart :: FileChar ( chars) => {
344
+ let start = self . cursor . cur_cursor ( ) ;
345
+ let Ok ( Some ( end) ) = self . cursor . next_boundary ( self . path , 0 ) else {
346
+ return None ;
354
347
} ;
355
-
356
- let c = & chars[ self . cursor . cur_cursor ( ) ..end]
357
- . iter ( )
358
- . cloned ( )
359
- . collect :: < String > ( ) ;
360
- if self . path . starts_with ( c) {
361
- return Some ( ( & self . path [ c. len ( ) ..] , false ) ) ;
348
+ let mut chars_in_path = self . path [ start..end] . chars ( ) ;
349
+ let Some ( c) = chars_in_path. next ( ) else {
350
+ return None ;
351
+ } ;
352
+ if chars_in_path. next ( ) . is_some ( ) {
353
+ return None ;
362
354
}
363
- } ,
355
+ chars. contains ( & c) . then ( || ( & self . path [ end..] , false ) )
356
+ }
364
357
GlobPart :: File ( name) => {
365
358
if self . cursor . cur_cursor ( ) == 0 && self . path . starts_with ( name) {
366
- let end = self . cursor . next_boundary ( self . path , 0 ) ;
367
- match end {
368
- Ok ( Some ( _) ) => { }
369
- Ok ( None ) => return None ,
370
- Err ( ..) => return None ,
371
- }
359
+ let Ok ( Some ( _) ) = self . cursor . next_boundary ( self . path , 0 ) else {
360
+ return None ;
361
+ } ;
372
362
Some ( ( & self . path [ name. len ( ) ..] , false ) )
373
363
} else {
374
364
None
@@ -379,15 +369,10 @@ impl<'a> Iterator for GlobPartMatchesIterator<'a> {
379
369
if let Some ( ( path, is_path_separator_equivalent) ) = glob_iterator. next ( ) {
380
370
return Some ( ( path, is_path_separator_equivalent) ) ;
381
371
} else {
382
- let end = self . cursor . next_boundary ( self . path , 0 ) ;
372
+ self . index += 1 ;
383
373
self . glob_iterator = None ;
384
- match end {
385
- Ok ( Some ( _) ) => { }
386
- Ok ( None ) => return None ,
387
- Err ( ..) => return None ,
388
- }
389
374
}
390
- } else if let Some ( alternative) = alternatives. get ( self . cursor . cur_cursor ( ) ) {
375
+ } else if let Some ( alternative) = alternatives. get ( self . index ) {
391
376
self . glob_iterator = Some ( Box :: new ( alternative. iter_matches (
392
377
self . path ,
393
378
self . previous_part_is_path_separator_equivalent ,
@@ -457,19 +442,43 @@ mod tests {
457
442
"node_modules/next/dist/server/next.js"
458
443
) ]
459
444
#[ case:: node_modules_root( "**/node_modules/**" , "node_modules/next/dist/server/next.js" ) ]
445
+ #[ case:: node_modules_root_package(
446
+ "**/node_modules/next/**" ,
447
+ "node_modules/next/dist/server/next.js"
448
+ ) ]
460
449
#[ case:: node_modules_nested(
461
450
"**/node_modules/**" ,
462
451
"apps/some-app/node_modules/regenerate-unicode-properties/Script_Extensions/Osage.js"
463
452
) ]
453
+ #[ case:: node_modules_nested_package(
454
+ "**/node_modules/regenerate-unicode-properties/**" ,
455
+ "apps/some-app/node_modules/regenerate-unicode-properties/Script_Extensions/Osage.js"
456
+ ) ]
464
457
#[ case:: node_modules_pnpm(
465
458
"**/node_modules/**" ,
466
459
"node_modules/.pnpm/[email protected] /node_modules/\
467
460
regenerate-unicode-properties/Script_Extensions/Osage.js"
468
461
) ]
462
+ #[ case:: node_modules_pnpm_package(
463
+ "**/node_modules/{regenerate,regenerate-unicode-properties}/**" ,
464
+ "node_modules/.pnpm/[email protected] /node_modules/\
465
+ regenerate-unicode-properties/Script_Extensions/Osage.js"
466
+ ) ]
467
+ #[ case:: node_modules_pnpm_prefixed_package(
468
+ "**/node_modules/{@blockfrost/blockfrost-js,@highlight-run/node,@libsql/client,@jpg-store/\
469
+ lucid-cardano,@mikro-orm/core,@mikro-orm/knex,@prisma/client,@sentry/nextjs,@sentry/node,\
470
+ @swc/core,argon2,autoprefixer,bcrypt,better-sqlite3,canvas,cpu-features,cypress,eslint,\
471
+ express,next-seo,node-pty,payload,pg,playwright,postcss,prettier,prisma,puppeteer,rimraf,\
472
+ sharp,shiki,sqlite3,tailwindcss,ts-node,typescript,vscode-oniguruma,webpack,websocket,@\
473
+ aws-sdk/client-dynamodb,@aws-sdk/lib-dynamodb}/**",
474
+
475
+ node_modules/@aws-sdk/lib-dynamodb/dist-es/index.js"
476
+ ) ]
469
477
#[ case:: alternatives_nested1( "{a,b/c,d/e/{f,g/h}}" , "a" ) ]
470
478
#[ case:: alternatives_nested2( "{a,b/c,d/e/{f,g/h}}" , "b/c" ) ]
471
479
#[ case:: alternatives_nested3( "{a,b/c,d/e/{f,g/h}}" , "d/e/f" ) ]
472
480
#[ case:: alternatives_nested4( "{a,b/c,d/e/{f,g/h}}" , "d/e/g/h" ) ]
481
+ // #[case::alternatives_chars("[abc]", "b")]
473
482
fn glob_match ( #[ case] glob : & str , #[ case] path : & str ) {
474
483
let glob = Glob :: parse ( glob) . unwrap ( ) ;
475
484
0 commit comments