Skip to main content

query_forge/output/formats/
csv.rs

1use crate::QueryResult;
2use crate::value::display_value;
3
4use super::utils::escape_csv_field;
5
6pub fn write_csv<W: std::io::Write + ?Sized>(
7    result: &QueryResult,
8    writer: &mut W,
9) -> std::io::Result<()> {
10    write_csv_row(result.columns.iter().map(String::as_str), writer)?;
11
12    for row in &result.rows {
13        writer.write_all(b"\n")?;
14        write_csv_row(row.iter().map(display_value), writer)?;
15    }
16
17    Ok(())
18}
19
20pub fn render_csv(result: &QueryResult) -> String {
21    let mut output = Vec::new();
22    write_csv(result, &mut output).expect("writing to memory cannot fail");
23    String::from_utf8(output).expect("CSV output should always be valid UTF-8")
24}
25
26fn write_csv_row<I, S, W>(fields: I, writer: &mut W) -> std::io::Result<()>
27where
28    I: IntoIterator<Item = S>,
29    S: AsRef<str>,
30    W: std::io::Write + ?Sized,
31{
32    for (index, field) in fields.into_iter().enumerate() {
33        if index > 0 {
34            writer.write_all(b",")?;
35        }
36        writer.write_all(escape_csv_field(field.as_ref()).as_bytes())?;
37    }
38    Ok(())
39}