Looping over (key, value) and add to string

Is there a more rust way of doing the following?

fn main() {
    let headers : std::vec::Vec<(String, String)> = vec![
        ("Header1".into(), "a".into()),
        ("Header2".into(), "b".into())
    ];

    let mut s : String = "".into();
    for (key, value) in headers.iter() {
        s = format!("{}\n{}:{}", s, key, value);
    }
    
    println!("{}", s);

}

In general, instead of

s = format!("{}…fmt…", s, …args…);

one should use

write!(s, "…fmt"…, …args…).unwrap();

because it can be more efficient (and looks nicer).

use std::fmt::Write;

fn main() {
    let headers: std::vec::Vec<(String, String)> = vec![
        ("Header1".into(), "a".into()),
        ("Header2".into(), "b".into()),
    ];

    let mut s: String = "".into();
    for (key, value) in headers.iter() {
        writeln!(s, "{}:{}", key, value).unwrap();
    }

    print!("{}", s);
}

For conveniently formatting items of an iterator, the itertools crate also has some helpers.

use itertools::Itertools;

fn main() {
    let headers: std::vec::Vec<(String, String)> = vec![
        ("Header1".into(), "a".into()),
        ("Header2".into(), "b".into()),
    ];

    let s = headers
        .iter()
        .format_with("\n", |(key, value), f| {
            f(&format_args!("{}:{}", key, value))
        })
        .to_string(); // `to_string` could be skipped e. g. if used only for printing

    println!("{}", s);
}
5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.