Skip to content

Instantly share code, notes, and snippets.

@skull-squadron
Last active May 20, 2025 04:30
Show Gist options
  • Save skull-squadron/7204f92db15ddab3f708f5fed68e4033 to your computer and use it in GitHub Desktop.
Save skull-squadron/7204f92db15ddab3f708f5fed68e4033 to your computer and use it in GitHub Desktop.
Rust replace beginning of string generically
use std::borrow::Cow;
pub trait ReplaceBeginning<'a>: Into<Cow<'a, str>> {
fn replace_beginning(
self,
prefix: impl AsRef<str>,
replacement: impl AsRef<str>,
) -> Cow<'a, str> {
let new_self = self.into();
let prefix = prefix.as_ref();
if !new_self.starts_with(prefix) {
return new_self;
}
let mut result = new_self.to_string();
result.replace_range(..prefix.len(), replacement.as_ref());
result.into()
}
}
impl<'a, T: Into<Cow<'a, str>>> ReplaceBeginning<'a> for T {}
pub trait ReplaceEnding<'a>: Into<Cow<'a, str>> {
fn replace_ending(self, prefix: impl AsRef<str>, replacement: impl AsRef<str>) -> Cow<'a, str> {
let new_self = self.into();
let prefix = prefix.as_ref();
if !new_self.ends_with(prefix) {
return new_self;
}
let mut result = new_self.to_string();
result.replace_range(new_self.len() - prefix.len().., replacement.as_ref());
result.into()
}
}
impl<'a, T: Into<Cow<'a, str>>> ReplaceEnding<'a> for T {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_replace_beginning() {
let s = "hello world";
let result = s.replace_beginning("hello", "hi");
assert_eq!(result, "hi world");
}
#[test]
fn test_replace_beginning_no_change() {
let s = "hello world";
let result = s.replace_beginning("xyz", "hi");
assert_eq!(result, s);
}
#[test]
fn test_prepend() {
let s = "world";
let result = s.replace_beginning("", "hello, ");
assert_eq!(result, "hello, world");
}
#[test]
fn test_replace_ending() {
let s = "hello world";
let result = s.replace_ending("world", "everyone");
assert_eq!(result, "hello everyone");
}
#[test]
fn test_replace_ending_no_change() {
let s = "hello world";
let result = s.replace_ending("xyz", "hi");
assert_eq!(result, s);
}
#[test]
fn test_replace_ending_one_char() {
let s = "hello world";
let result = s.replace_ending("d", "ds");
assert_eq!(result, "hello worlds");
}
#[test]
fn test_append_ending() {
let s = "hello world";
let result = s.replace_ending("", "s");
assert_eq!(result, "hello worlds");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment