Strings and Text Processing

insert() and insert_str()

The .insert() and .insert_str() methods splice a char or &str into a String at a specified UTF-8 byte index, shifting all subsequent bytes to the right.

Signatures and Complexity

impl String {
    pub fn insert(&mut self, idx: usize, ch: char);
    pub fn insert_str(&mut self, idx: usize, string: &str);
}
Before `s.insert_str(4, "2024 ")`:
+---+---+---+---+---+---+---+---+
| R | u | s | t | E | d | . |   |
+---+---+---+---+---+---+---+---+
                  ▲ (idx = 4)

After shifting bytes [4..7] right by 5 bytes and copying "2024 ":
+---+---+---+---+---+---+---+---+---+---+---+---+
| R | u | s | t | 2 | 0 | 2 | 4 |   | E | d | . |
+---+---+---+---+---+---+---+---+---+---+---+---+
  • Time complexity: $O(n)$ where $n$ is the number of bytes after idx that must be shifted (std::ptr::copy), plus the length of the inserted text.
  • Panics: Both methods panic if idx > self.len() or if idx does not lie on a valid UTF-8 character boundary (!self.is_char_boundary(idx)).

Inserting Characters and Slices at Valid Byte Offsets

fn main() {
    let mut title = String::from("Rust Guide");

    // Insert a string slice at byte index 5 (right before "Guide"):
    title.insert_str(5, "2024 ");

    // Insert a character at byte index 0 (prepend) and at the end (`title.len()`):
    title.insert(0, '[');
    title.insert(title.len(), ']');

    println!("{title}");
}
[Rust 2024 Guide]

Replacing a Byte Range In-Place with replace_range()

When you want to both delete a byte range and insert a new &str at that position in a single shift operation, use s.replace_range(range, replace_with) instead of calling .drain() followed by .insert_str():

fn main() {
    let mut url = String::from("http://example.com/api");

    // Replaces "http" (0..4) with "https" in one operation:
    url.replace_range(0..4, "https");

    println!("{url}");
}
https://example.com/api