query_forge/output/formats/
csv.rs1use 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}