55// spell-checker:ignore anotherfile invalidchecksum regexes JWZG FFFD xffname prefixfilename
66
77use data_encoding:: BASE64 ;
8+ use lazy_static:: lazy_static;
89use os_display:: Quotable ;
910use regex:: bytes:: { Match , Regex } ;
1011use std:: {
@@ -428,35 +429,46 @@ const DOUBLE_SPACE_REGEX: &str = r"^(?P<checksum>[a-fA-F0-9]+)\s{2}(?P<filename>
428429// In this case, we ignore the *
429430const SINGLE_SPACE_REGEX : & str = r"^(?P<checksum>[a-fA-F0-9]+)\s(?P<filename>\*?(?-u:.*))$" ;
430431
432+ lazy_static ! {
433+ static ref R_ALGO_BASED : Regex = Regex :: new( ALGO_BASED_REGEX ) . unwrap( ) ;
434+ static ref R_DOUBLE_SPACE : Regex = Regex :: new( DOUBLE_SPACE_REGEX ) . unwrap( ) ;
435+ static ref R_SINGLE_SPACE : Regex = Regex :: new( SINGLE_SPACE_REGEX ) . unwrap( ) ;
436+ static ref R_ALGO_BASED_BASE_64 : Regex = Regex :: new( ALGO_BASED_REGEX_BASE64 ) . unwrap( ) ;
437+ }
438+
431439/// Hold the data extracted from a checksum line.
432440struct LineInfo {
433441 algo_name : Option < String > ,
434442 algo_bit_len : Option < usize > ,
435443 checksum : String ,
436444 filename : Vec < u8 > ,
437445
438- regex : Regex ,
446+ regex : & ' static Regex ,
439447}
440448
441449impl LineInfo {
442- fn parse ( s : impl AsRef < OsStr > , cached_regex : & mut Option < Regex > ) -> Option < Self > {
443- let regexes = [
444- ( Regex :: new ( ALGO_BASED_REGEX ) . unwrap ( ) , true ) ,
445- ( Regex :: new ( DOUBLE_SPACE_REGEX ) . unwrap ( ) , false ) ,
446- ( Regex :: new ( SINGLE_SPACE_REGEX ) . unwrap ( ) , false ) ,
447- ( Regex :: new ( ALGO_BASED_REGEX_BASE64 ) . unwrap ( ) , false ) ,
450+ fn parse ( s : impl AsRef < OsStr > , cached_regex : & mut Option < & ' static Regex > ) -> Option < Self > {
451+ let regexes: & [ ( & ' static Regex , bool ) ] = & [
452+ ( & R_ALGO_BASED , true ) ,
453+ ( & R_DOUBLE_SPACE , false ) ,
454+ ( & R_SINGLE_SPACE , false ) ,
455+ ( & R_ALGO_BASED_BASE_64 , true ) ,
448456 ] ;
449457
450458 let line_bytes = os_str_as_bytes ( s. as_ref ( ) ) . expect ( "UTF-8 decoding failed" ) ;
451459
452- for ( regex, algo_based) in & regexes {
460+ for ( regex, algo_based) in regexes {
453461 if !regex. is_match ( line_bytes) {
454462 continue ;
455463 }
456464
457- let mut r = regex. clone ( ) ;
458- if !algo_based && cached_regex. is_some ( ) {
459- r = cached_regex. clone ( ) . unwrap ( ) ;
465+ let mut r = * regex;
466+ if !algo_based {
467+ if cached_regex. is_some ( ) {
468+ r = cached_regex. unwrap ( ) ;
469+ } else {
470+ * cached_regex = Some ( r) ;
471+ }
460472 }
461473
462474 if let Some ( caps) = r. captures ( line_bytes) {
@@ -470,7 +482,7 @@ impl LineInfo {
470482 . map ( |m| match_to_string ( m) . parse :: < usize > ( ) . unwrap ( ) ) ,
471483 checksum : caps. name ( "checksum" ) . map ( match_to_string) . unwrap ( ) ,
472484 filename : caps. name ( "filename" ) . map ( |m| m. as_bytes ( ) . into ( ) ) . unwrap ( ) ,
473- regex : r. clone ( ) ,
485+ regex : r,
474486 } ) ;
475487 }
476488 }
@@ -638,7 +650,7 @@ fn process_checksum_line(
638650 cli_algo_name : Option < & str > ,
639651 cli_algo_length : Option < usize > ,
640652 opts : ChecksumOptions ,
641- cached_regex : & mut Option < Regex > ,
653+ cached_regex : & mut Option < & ' static Regex > ,
642654) -> Result < ( ) , LineCheckError > {
643655 let line_bytes = os_str_as_bytes ( line) ?;
644656
@@ -652,7 +664,7 @@ fn process_checksum_line(
652664 // its cannot be changed (can't have single and double space regexes
653665 // used in the same file).
654666 if cached_regex. is_none ( ) && !line_info. is_algo_based ( ) {
655- let _ = cached_regex. insert ( line_info. regex . clone ( ) ) ;
667+ let _ = cached_regex. insert ( line_info. regex ) ;
656668 }
657669
658670 let mut filename_to_check = line_info. filename . as_slice ( ) ;
0 commit comments