Rust render aligned plain-text terminal table

Rust
fn render(headers: &[&str], rows: &[Vec<&str>]) -> String {
    let cols = headers.len();
    let mut widths: Vec<usize> = headers.iter().map(|h| h.chars().count()).collect();
    for row in rows {
        for (i, cell) in row.iter().enumerate().take(cols) {
            widths[i] = widths[i].max(cell.chars().count());
        }
    }
    let line = |cells: &[&str]| (0..cols).map(|i| {
        format!("{:<width$}", cells.get(i).copied().unwrap_or(""), width = widths[i])
    }).collect::<Vec<_>>().join(" | ");
    let mut out = vec![line(headers)];
    let sep: String = widths.iter().map(|w| "-".repeat(*w)).collect::<Vec<_>>().join("-+-");
    out.push(sep);
    out.extend(rows.iter().map(|r| line(r.as_slice())));
    out.join("\n")
}