use crate::QueryResult;
use crate::value::display_value;
use super::utils::escape_csv_field;
pub fn write_csv<W: std::io::Write + ?Sized>(
result: &QueryResult,
writer: &mut W,
) -> std::io::Result<()> {
write_csv_row(result.columns.iter().map(String::as_str), writer)?;
for row in &result.rows {
writer.write_all(b"\n")?;
write_csv_row(row.iter().map(display_value), writer)?;
}
Ok(())
}
pub fn render_csv(result: &QueryResult) -> String {
let mut output = Vec::new();
write_csv(result, &mut output).expect("writing to memory cannot fail");
String::from_utf8(output).expect("CSV output should always be valid UTF-8")
}
fn write_csv_row<I, S, W>(fields: I, writer: &mut W) -> std::io::Result<()>
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
W: std::io::Write + ?Sized,
{
for (index, field) in fields.into_iter().enumerate() {
if index > 0 {
writer.write_all(b",")?;
}
writer.write_all(escape_csv_field(field.as_ref()).as_bytes())?;
}
Ok(())
}