RustArena

Step 2 of 6

Growing a String with push_str and push

A String can grow. Two methods add text at the end:

fn main() {
    let mut log = String::new();
    log.push_str("user=ferris");
    log.push(';');
    log.push_str(" action=login");
    println!("{log}");
}
user=ferris; action=login

Building text in a loop

Growing a String piece by piece is how you build text whose shape depends on data. Here's a progress bar:

fn main() {
    let done = 3;
    let total = 8;
    let mut bar = String::new();
    for i in 0..total {
        if i < done {
            bar.push('#');
        } else {
            bar.push('.');
        }
    }
    println!("[{bar}] {done}/{total}");
}
[###.....] 3/8

A String reserves extra room as it grows, so pushing many small pieces is cheap. You don't need to know the final length in advance.

Common mistakes

fn main() {
    let mut s = String::from("hi");
    s.push("!");
    println!("{s}");
}
error[E0308]: mismatched types

The message says expected `char`, found `&str` and suggests '!'. Use s.push('!') for one character or s.push_str("!") for text.

Your task

Fill in the blanks so the version tag grows from v1 to v1.2.0: push a single '.' character, then the text "2.0".

Challenge 2

Write progress_bar(done, total), which returns a bar with one # per finished step and one . per remaining step, inside square brackets. For example progress_bar(3, 8) returns "[###.....]". You can assume done is never bigger than total.

Challenge 3

Print an 8 × 8 chessboard. Square (row, col) is # when row + col is even and . when it's odd. Build each row as a String with push, then print it:

#.#.#.#.
.#.#.#.#
#.#.#.#.
.#.#.#.#
#.#.#.#.
.#.#.#.#
#.#.#.#.
.#.#.#.#

Previous: Two kinds of string: &str and String Next: Joining text: format! and +