@@ -504,22 +504,42 @@ impl Attribute {
504
504
}
505
505
}
506
506
507
+ // A naive way to determine if a path is a Windows path.
508
+ // If the path has a drive letter and more backslashes than forward slashes, it's a Windows path.
509
+ fn is_windows_path ( path : & str ) -> bool {
510
+ use once_cell:: sync:: OnceCell ;
511
+ use regex:: Regex ;
512
+
513
+ static REGEX : OnceCell < Regex > = OnceCell :: new ( ) ;
514
+ let regex = REGEX . get_or_init ( || Regex :: new ( r"^[a-zA-Z]:\\" ) . expect ( "failed to compile regex" ) ) ;
515
+ let has_drive_letter = regex. is_match ( path) ;
516
+ let slash_count = path. chars ( ) . filter ( |& c| c == '/' ) . count ( ) ;
517
+ let backslash_count = path. chars ( ) . filter ( |& c| c == '\\' ) . count ( ) ;
518
+ has_drive_letter && backslash_count > slash_count
519
+ }
520
+
507
521
fn truncate_registry_path ( s : String ) -> String {
508
522
use once_cell:: sync:: OnceCell ;
509
523
use regex:: Regex ;
510
524
use std:: borrow:: Cow ;
511
525
512
526
static REGEX : OnceCell < Regex > = OnceCell :: new ( ) ;
513
527
let regex = REGEX . get_or_init ( || {
514
- Regex :: new ( r".*/\ .cargo(/ registry/ src/ [^/]*/|/ git/ checkouts/ )" )
528
+ Regex :: new ( r".*[/\\]\ .cargo[/\\]( registry[/\\] src[/\\] [^/\\]*[/\\]| git[/\\] checkouts[/\\] )" )
515
529
. expect ( "failed to compile regex" )
516
530
} ) ;
517
531
518
- return match regex. replace ( & s, "<cargo>/" ) {
532
+ let rep = if is_windows_path ( & s) {
533
+ "<cargo>\\ "
534
+ } else {
535
+ "<cargo>/"
536
+ } ;
537
+
538
+ match regex. replace ( & s, rep) {
519
539
Cow :: Owned ( s) => s,
520
540
// String was not modified, return the original.
521
- Cow :: Borrowed ( _) => s. to_string ( ) ,
522
- } ;
541
+ Cow :: Borrowed ( _) => s,
542
+ }
523
543
}
524
544
525
545
fn format_location ( loc : Option < proto:: Location > ) -> String {
@@ -586,30 +606,69 @@ mod tests {
586
606
#[ test]
587
607
fn test_format_location_macos ( ) {
588
608
// macOS style paths.
589
- let location4 = proto:: Location {
609
+ let location1 = proto:: Location {
590
610
file : Some ( "/Users/user/.cargo/registry/src/gb.xjqchip.workers.dev-1ecc6299db9ec823/tokio-1.0.1/src/lib.rs" . to_string ( ) ) ,
591
611
..Default :: default ( )
592
612
} ;
593
- let location5 = proto:: Location {
613
+ let location2 = proto:: Location {
594
614
file : Some ( "/Users/user/.cargo/git/checkouts/tokio-1.0.1/src/lib.rs" . to_string ( ) ) ,
595
615
..Default :: default ( )
596
616
} ;
597
- let location6 = proto:: Location {
617
+ let location3 = proto:: Location {
598
618
file : Some ( "/Users/user/projects/tokio-1.0.1/src/lib.rs" . to_string ( ) ) ,
599
619
..Default :: default ( )
600
620
} ;
601
621
602
622
assert_eq ! (
603
- format_location( Some ( location4 ) ) ,
623
+ format_location( Some ( location1 ) ) ,
604
624
"<cargo>/tokio-1.0.1/src/lib.rs"
605
625
) ;
606
626
assert_eq ! (
607
- format_location( Some ( location5 ) ) ,
627
+ format_location( Some ( location2 ) ) ,
608
628
"<cargo>/tokio-1.0.1/src/lib.rs"
609
629
) ;
610
630
assert_eq ! (
611
- format_location( Some ( location6 ) ) ,
631
+ format_location( Some ( location3 ) ) ,
612
632
"/Users/user/projects/tokio-1.0.1/src/lib.rs"
613
633
) ;
614
634
}
635
+
636
+ #[ test]
637
+ fn test_format_location_windows ( ) {
638
+ // Windows style paths.
639
+ let location1 = proto:: Location {
640
+ file : Some (
641
+ "C:\\ Users\\ user\\ .cargo\\ registry\\ src\\ gb.xjqchip.workers.dev-1ecc6299db9ec823\\ tokio-1.0.1\\ src\\ lib.rs"
642
+ . to_string ( ) ,
643
+ ) ,
644
+ ..Default :: default ( )
645
+ } ;
646
+
647
+ let location2 = proto:: Location {
648
+ file : Some (
649
+ "C:\\ Users\\ user\\ .cargo\\ git\\ checkouts\\ tokio-1.0.1\\ src\\ lib.rs" . to_string ( ) ,
650
+ ) ,
651
+ ..Default :: default ( )
652
+ } ;
653
+
654
+ let location3 = proto:: Location {
655
+ file : Some ( "C:\\ Users\\ user\\ projects\\ tokio-1.0.1\\ src\\ lib.rs" . to_string ( ) ) ,
656
+ ..Default :: default ( )
657
+ } ;
658
+
659
+ assert_eq ! (
660
+ format_location( Some ( location1) ) ,
661
+ "<cargo>\\ tokio-1.0.1\\ src\\ lib.rs"
662
+ ) ;
663
+
664
+ assert_eq ! (
665
+ format_location( Some ( location2) ) ,
666
+ "<cargo>\\ tokio-1.0.1\\ src\\ lib.rs"
667
+ ) ;
668
+
669
+ assert_eq ! (
670
+ format_location( Some ( location3) ) ,
671
+ "C:\\ Users\\ user\\ projects\\ tokio-1.0.1\\ src\\ lib.rs"
672
+ ) ;
673
+ }
615
674
}
0 commit comments