diff options
| author | Shoyu Vanilla (Flint) <modulo641@gmail.com> | 2025-09-20 13:32:39 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-20 13:32:39 +0000 |
| commit | c8182c4ae3f40b77e12db4980433ca1a9a1b59a1 (patch) | |
| tree | 9831bea2714157e64a6cf6e47f0228085b7a620b | |
| parent | 3810e1732be762d851d9d3a1d2fca132d4b0aff5 (diff) | |
| parent | c38c6b862851b6ff1a897037e1cb16898cfbf44f (diff) | |
| download | rust-c8182c4ae3f40b77e12db4980433ca1a9a1b59a1.tar.gz rust-c8182c4ae3f40b77e12db4980433ca1a9a1b59a1.zip | |
Merge pull request #20706 from A4-Tacks/stdx-replace-inplace
Fix to implements in-place stdx::replace
| -rw-r--r-- | src/tools/rust-analyzer/crates/stdx/src/lib.rs | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs index 978c50d807b..5fa00741637 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs @@ -187,11 +187,19 @@ pub fn is_upper_snake_case(s: &str) -> bool { } pub fn replace(buf: &mut String, from: char, to: &str) { - if !buf.contains(from) { + let replace_count = buf.chars().filter(|&ch| ch == from).count(); + if replace_count == 0 { return; } - // FIXME: do this in place. - *buf = buf.replace(from, to); + let from_len = from.len_utf8(); + let additional = to.len().saturating_sub(from_len); + buf.reserve(additional * replace_count); + + let mut end = buf.len(); + while let Some(i) = buf[..end].rfind(from) { + buf.replace_range(i..i + from_len, to); + end = i; + } } #[must_use] @@ -343,4 +351,34 @@ mod tests { "fn main() {\n return 92;\n}\n" ); } + + #[test] + fn test_replace() { + #[track_caller] + fn test_replace(src: &str, from: char, to: &str, expected: &str) { + let mut s = src.to_owned(); + replace(&mut s, from, to); + assert_eq!(s, expected, "from: {from:?}, to: {to:?}"); + } + + test_replace("", 'a', "b", ""); + test_replace("", 'a', "😀", ""); + test_replace("", '😀', "a", ""); + test_replace("a", 'a', "b", "b"); + test_replace("aa", 'a', "b", "bb"); + test_replace("ada", 'a', "b", "bdb"); + test_replace("a", 'a', "😀", "😀"); + test_replace("😀", '😀', "a", "a"); + test_replace("😀x", '😀', "a", "ax"); + test_replace("y😀x", '😀', "a", "yax"); + test_replace("a,b,c", ',', ".", "a.b.c"); + test_replace("a,b,c", ',', "..", "a..b..c"); + test_replace("a.b.c", '.', "..", "a..b..c"); + test_replace("a.b.c", '.', "..", "a..b..c"); + test_replace("a😀b😀c", '😀', ".", "a.b.c"); + test_replace("a.b.c", '.', "😀", "a😀b😀c"); + test_replace("a.b.c", '.', "😀😀", "a😀😀b😀😀c"); + test_replace(".a.b.c.", '.', "()", "()a()b()c()"); + test_replace(".a.b.c.", '.', "", "abc"); + } } |
