use std::fmt::Write as _;
use crate::QueryResult;
use crate::value::display_value;
pub fn render_text(result: &QueryResult) -> String {
if result.columns.is_empty() {
return String::new();
}
let mut column_widths = result
.columns
.iter()
.map(|column| column.len())
.collect::<Vec<_>>();
let mut rendered_rows = Vec::with_capacity(result.rows.len());
for row in &result.rows {
let mut rendered_row = Vec::with_capacity(result.columns.len());
for index in 0..result.columns.len() {
let rendered_value = row.get(index).map(display_value).unwrap_or_default();
column_widths[index] = column_widths[index].max(rendered_value.len());
rendered_row.push(rendered_value);
}
rendered_rows.push(rendered_row);
}
let mut output = String::new();
write_aligned_row(&mut output, &result.columns, &column_widths);
output.push('\n');
output.push_str(
&column_widths
.iter()
.map(|width| "-".repeat(*width))
.collect::<Vec<_>>()
.join("-+-"),
);
for row in rendered_rows {
output.push('\n');
write_aligned_row(&mut output, &row, &column_widths);
}
output
}
fn write_aligned_row(output: &mut String, values: &[String], column_widths: &[usize]) {
for (index, value) in values.iter().enumerate() {
if index > 0 {
output.push_str(" | ");
}
let _ = write!(output, "{value:<width$}", width = column_widths[index]);
}
}