Skip to content

Commit 187917f

Browse files
authored
Merge pull request #20706 from A4-Tacks/stdx-replace-inplace
Fix to implements in-place stdx::replace
2 parents a003d4d + 29de96c commit 187917f

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

β€Žcrates/stdx/src/lib.rsβ€Ž

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,19 @@ pub fn is_upper_snake_case(s: &str) -> bool {
187187
}
188188

189189
pub fn replace(buf: &mut String, from: char, to: &str) {
190-
if !buf.contains(from) {
190+
let replace_count = buf.chars().filter(|&ch| ch == from).count();
191+
if replace_count == 0 {
191192
return;
192193
}
193-
// FIXME: do this in place.
194-
*buf = buf.replace(from, to);
194+
let from_len = from.len_utf8();
195+
let additional = to.len().saturating_sub(from_len);
196+
buf.reserve(additional * replace_count);
197+
198+
let mut end = buf.len();
199+
while let Some(i) = buf[..end].rfind(from) {
200+
buf.replace_range(i..i + from_len, to);
201+
end = i;
202+
}
195203
}
196204

197205
#[must_use]
@@ -343,4 +351,34 @@ mod tests {
343351
"fn main() {\n return 92;\n}\n"
344352
);
345353
}
354+
355+
#[test]
356+
fn test_replace() {
357+
#[track_caller]
358+
fn test_replace(src: &str, from: char, to: &str, expected: &str) {
359+
let mut s = src.to_owned();
360+
replace(&mut s, from, to);
361+
assert_eq!(s, expected, "from: {from:?}, to: {to:?}");
362+
}
363+
364+
test_replace("", 'a', "b", "");
365+
test_replace("", 'a', "πŸ˜€", "");
366+
test_replace("", 'πŸ˜€', "a", "");
367+
test_replace("a", 'a', "b", "b");
368+
test_replace("aa", 'a', "b", "bb");
369+
test_replace("ada", 'a', "b", "bdb");
370+
test_replace("a", 'a', "πŸ˜€", "πŸ˜€");
371+
test_replace("πŸ˜€", 'πŸ˜€', "a", "a");
372+
test_replace("πŸ˜€x", 'πŸ˜€', "a", "ax");
373+
test_replace("yπŸ˜€x", 'πŸ˜€', "a", "yax");
374+
test_replace("a,b,c", ',', ".", "a.b.c");
375+
test_replace("a,b,c", ',', "..", "a..b..c");
376+
test_replace("a.b.c", '.', "..", "a..b..c");
377+
test_replace("a.b.c", '.', "..", "a..b..c");
378+
test_replace("aπŸ˜€bπŸ˜€c", 'πŸ˜€', ".", "a.b.c");
379+
test_replace("a.b.c", '.', "πŸ˜€", "aπŸ˜€bπŸ˜€c");
380+
test_replace("a.b.c", '.', "πŸ˜€πŸ˜€", "aπŸ˜€πŸ˜€bπŸ˜€πŸ˜€c");
381+
test_replace(".a.b.c.", '.', "()", "()a()b()c()");
382+
test_replace(".a.b.c.", '.', "", "abc");
383+
}
346384
}

0 commit comments

Comments
Β (0)