@@ -23,6 +23,11 @@ pub static UPDATE: Lazy<bool> = Lazy::new(|| env::var("UPDATE").unwrap_or_defaul
2323
2424static ANSI_REGEX : Lazy < Regex > = Lazy :: new ( || Regex :: new ( r"\x1b\[\d+m" ) . unwrap ( ) ) ;
2525
26+ // Matches characters that are not allowed or problematic in filenames
27+ static INVALID_FILENAME_CHARS : Lazy < Regex > = Lazy :: new ( || Regex :: new ( r#"[/:*?"<>|'\\]+"# ) . unwrap ( ) ) ;
28+ // Matches multiple spaces or dashes
29+ static MULTI_SPACE_DASH : Lazy < Regex > = Lazy :: new ( || Regex :: new ( r"[\s-]+" ) . unwrap ( ) ) ;
30+
2631pub async fn snapshot_issues < I : IntoIterator < Item = ReadRef < PlainIssue > > > (
2732 captured_issues : I ,
2833 issues_path : FileSystemPath ,
@@ -31,17 +36,15 @@ pub async fn snapshot_issues<I: IntoIterator<Item = ReadRef<PlainIssue>>>(
3136 let expected_issues = expected ( issues_path. clone ( ) ) . await ?;
3237 let mut seen = FxHashSet :: default ( ) ;
3338 for plain_issue in captured_issues. into_iter ( ) {
34- let title = styled_string_to_file_safe_string ( & plain_issue. title )
35- . replace ( '/' , "__" )
36- // We replace "*", "?", and '"' because they're not allowed in filenames on Windows.
37- . replace ( '*' , "__star__" )
38- . replace ( '"' , "__quo__" )
39- . replace ( '?' , "__q__" )
40- . replace ( ':' , "__c__" ) ;
39+ let title = styled_string_to_file_safe_string ( & plain_issue. title ) ;
40+ // Replace invalid filename characters with space, then normalize spaces/dashes
41+ let title = INVALID_FILENAME_CHARS . replace_all ( & title, " " ) ;
42+ let title = MULTI_SPACE_DASH . replace_all ( & title, "-" ) ;
43+ let title = title. trim_matches ( '-' ) ;
4144 let title = if title. len ( ) > 50 {
4245 & title[ 0 ..50 ]
4346 } else {
44- & title
47+ title
4548 } ;
4649 let hash = encode_hex ( plain_issue. internal_hash_ref ( true ) ) ;
4750
@@ -212,27 +215,13 @@ async fn diff_paths(
212215
213216fn styled_string_to_file_safe_string ( styled_string : & StyledString ) -> String {
214217 match styled_string {
215- StyledString :: Line ( parts) => {
216- let mut string = String :: new ( ) ;
217- string += "__l_" ;
218- for part in parts {
219- string. push_str ( & styled_string_to_file_safe_string ( part) ) ;
220- }
221- string += "__" ;
222- string
223- }
224- StyledString :: Stack ( parts) => {
225- let mut string = String :: new ( ) ;
226- string += "__s_" ;
227- for part in parts {
228- string. push_str ( & styled_string_to_file_safe_string ( part) ) ;
229- string. push ( '_' ) ;
230- }
231- string += "__" ;
232- string
218+ StyledString :: Line ( parts) | StyledString :: Stack ( parts) => parts
219+ . iter ( )
220+ . map ( styled_string_to_file_safe_string)
221+ . collect :: < Vec < _ > > ( )
222+ . join ( " " ) ,
223+ StyledString :: Text ( string) | StyledString :: Code ( string) | StyledString :: Strong ( string) => {
224+ string. to_string ( )
233225 }
234- StyledString :: Text ( string) => string. to_string ( ) ,
235- StyledString :: Code ( string) => format ! ( "__c_{string}__" ) ,
236- StyledString :: Strong ( string) => format ! ( "__{string}__" ) ,
237226 }
238227}
0 commit comments