@@ -371,6 +371,7 @@ pub fn get_compile_benchmarks(
371
371
benchmark_dir : & Path ,
372
372
include : Option < & str > ,
373
373
exclude : Option < & str > ,
374
+ exclude_suffix : Option < & str > ,
374
375
) -> anyhow:: Result < Vec < Benchmark > > {
375
376
let mut benchmarks = Vec :: new ( ) ;
376
377
@@ -405,25 +406,23 @@ pub fn get_compile_benchmarks(
405
406
406
407
let mut includes = to_hashmap ( include) ;
407
408
let mut excludes = to_hashmap ( exclude) ;
409
+ let mut exclude_suffixes = to_hashmap ( exclude_suffix) ;
408
410
409
411
for ( path, name) in paths {
410
412
let mut skip = false ;
411
413
412
- let name_matches = |prefixes : & mut HashMap < & str , usize > | {
413
- for ( prefix, n) in prefixes. iter_mut ( ) {
414
- if name. as_str ( ) . starts_with ( prefix) {
415
- * n += 1 ;
416
- return true ;
417
- }
418
- }
419
- false
414
+ let name_matches_prefix = |prefixes : & mut HashMap < & str , usize > | {
415
+ substring_matches ( prefixes, |prefix| name. starts_with ( prefix) )
420
416
} ;
421
417
422
418
if let Some ( includes) = includes. as_mut ( ) {
423
- skip |= !name_matches ( includes) ;
419
+ skip |= !name_matches_prefix ( includes) ;
424
420
}
425
421
if let Some ( excludes) = excludes. as_mut ( ) {
426
- skip |= name_matches ( excludes) ;
422
+ skip |= name_matches_prefix ( excludes) ;
423
+ }
424
+ if let Some ( exclude_suffixes) = exclude_suffixes. as_mut ( ) {
425
+ skip |= substring_matches ( exclude_suffixes, |suffix| name. ends_with ( suffix) ) ;
427
426
}
428
427
if skip {
429
428
continue ;
@@ -433,10 +432,10 @@ pub fn get_compile_benchmarks(
433
432
benchmarks. push ( Benchmark :: new ( name, path) ?) ;
434
433
}
435
434
436
- // All prefixes must be used at least once. This is to catch typos.
437
- let check_for_unused = |option, prefixes : Option < HashMap < & str , usize > > | {
438
- if let Some ( prefixes ) = prefixes {
439
- let unused: Vec < _ > = prefixes
435
+ // All prefixes/suffixes must be used at least once. This is to catch typos.
436
+ let check_for_unused = |option, substrings : Option < HashMap < & str , usize > > | {
437
+ if let Some ( substrings ) = substrings {
438
+ let unused: Vec < _ > = substrings
440
439
. into_iter ( )
441
440
. filter_map ( |( i, n) | if n == 0 { Some ( i) } else { None } )
442
441
. collect ( ) ;
@@ -453,6 +452,7 @@ pub fn get_compile_benchmarks(
453
452
454
453
check_for_unused ( "include" , includes) ?;
455
454
check_for_unused ( "exclude" , excludes) ?;
455
+ check_for_unused ( "exclude-suffix" , exclude_suffixes) ?;
456
456
457
457
benchmarks. sort_by_key ( |benchmark| benchmark. name . clone ( ) ) ;
458
458
@@ -462,3 +462,19 @@ pub fn get_compile_benchmarks(
462
462
463
463
Ok ( benchmarks)
464
464
}
465
+
466
+ /// Helper to verify if a benchmark name matches a given substring, like a prefix or a suffix. The
467
+ /// `predicate` closure will be passed each substring from `substrings` until it returns true, and
468
+ /// in that case the substring's number of uses in the map will be increased.
469
+ fn substring_matches (
470
+ substrings : & mut HashMap < & str , usize > ,
471
+ predicate : impl Fn ( & str ) -> bool ,
472
+ ) -> bool {
473
+ for ( substring, n) in substrings. iter_mut ( ) {
474
+ if predicate ( substring) {
475
+ * n += 1 ;
476
+ return true ;
477
+ }
478
+ }
479
+ false
480
+ }
0 commit comments