Skip to content

Commit bf0ce66

Browse files
authored
Merge pull request #345 from Muscraft/fix-replacement-trimming
fix: Prefer exact prefix/suffix matches when trimming replacements
2 parents ed71e38 + f33da7f commit bf0ce66

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

src/renderer/source_map.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -779,18 +779,24 @@ pub(crate) fn as_substr<'a>(
779779
original: &'a str,
780780
suggestion: &'a str,
781781
) -> Option<(usize, &'a str, usize)> {
782-
let common_prefix = original
783-
.chars()
784-
.zip(suggestion.chars())
785-
.take_while(|(c1, c2)| c1 == c2)
786-
.map(|(c, _)| c.len_utf8())
787-
.sum();
788-
let original = &original[common_prefix..];
789-
let suggestion = &suggestion[common_prefix..];
790-
if let Some(stripped) = suggestion.strip_suffix(original) {
791-
let common_suffix = original.len();
792-
Some((common_prefix, stripped, common_suffix))
782+
if let Some(stripped) = suggestion.strip_prefix(original) {
783+
Some((original.len(), stripped, 0))
784+
} else if let Some(stripped) = suggestion.strip_suffix(original) {
785+
Some((0, stripped, original.len()))
793786
} else {
794-
None
787+
let common_prefix = original
788+
.chars()
789+
.zip(suggestion.chars())
790+
.take_while(|(c1, c2)| c1 == c2)
791+
.map(|(c, _)| c.len_utf8())
792+
.sum();
793+
let original = &original[common_prefix..];
794+
let suggestion = &suggestion[common_prefix..];
795+
if let Some(stripped) = suggestion.strip_suffix(original) {
796+
let common_suffix = original.len();
797+
Some((common_prefix, stripped, common_suffix))
798+
} else {
799+
None
800+
}
795801
}
796802
}

tests/formatter.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5015,3 +5015,52 @@ help: consider importing this module
50155015
let renderer = renderer.decor_style(DecorStyle::Unicode);
50165016
assert_data_eq!(renderer.render(input), expected_unicode);
50175017
}
5018+
5019+
#[test]
5020+
fn original_matches_replacement_suffix() {
5021+
let source = r#"use sync;"#;
5022+
let input = &[
5023+
Group::with_level(Level::ERROR).element(
5024+
Snippet::source(source).path("/tmp/test.rs").annotation(
5025+
AnnotationKind::Primary
5026+
.span(4..8)
5027+
.label("no `sync` in the root"),
5028+
),
5029+
),
5030+
Level::HELP
5031+
.secondary_title("consider importing this module instead")
5032+
.element(
5033+
Snippet::source(source)
5034+
.path("/tmp/test.rs")
5035+
.patch(Patch::new(4..8, "std::sync")),
5036+
),
5037+
];
5038+
5039+
let expected_ascii = str![[r#"
5040+
--> /tmp/test.rs:1:5
5041+
|
5042+
1 | use sync;
5043+
| ^^^^ no `sync` in the root
5044+
|
5045+
help: consider importing this module instead
5046+
|
5047+
1 | use std::sync;
5048+
| +++++
5049+
"#]];
5050+
let renderer = Renderer::plain();
5051+
assert_data_eq!(renderer.render(input), expected_ascii);
5052+
5053+
let expected_unicode = str![[r#"
5054+
╭▸ /tmp/test.rs:1:5
5055+
5056+
1 │ use sync;
5057+
│ ━━━━ no `sync` in the root
5058+
╰╴
5059+
help: consider importing this module instead
5060+
╭╴
5061+
1 │ use std::sync;
5062+
╰╴ +++++
5063+
"#]];
5064+
let renderer = renderer.decor_style(DecorStyle::Unicode);
5065+
assert_data_eq!(renderer.render(input), expected_unicode);
5066+
}

0 commit comments

Comments
 (0)