use super::OutputFormatter;
use crate::types::GrepResult;
use anyhow::Result;
pub struct CsvFormatter {
delimiter: char,
}
impl CsvFormatter {
pub fn new() -> Self {
Self { delimiter: ',' }
}
pub fn with_delimiter(delimiter: char) -> Self {
Self { delimiter }
}
}
impl Default for CsvFormatter {
fn default() -> Self {
Self::new()
}
}
impl OutputFormatter for CsvFormatter {
fn format_result(&self, result: &GrepResult) -> Result<String> {
let mut output = String::new();
output.push_str(&format!(
"notebook{}cell_index{}cell_number{}execution_count{}match_type{}line_index{}line_number{}matched_text{}line_content\n",
self.delimiter, self.delimiter, self.delimiter, self.delimiter,
self.delimiter, self.delimiter, self.delimiter, self.delimiter
));
for m in &result.matches {
let exec_count = m.execution_count.map(|c| c.to_string()).unwrap_or_default();
output.push_str(&format!(
"\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"",
escape_csv(&result.notebook),
self.delimiter,
m.cell_index,
self.delimiter,
m.cell_number,
self.delimiter,
exec_count,
self.delimiter,
m.match_type,
self.delimiter,
m.line_index,
self.delimiter,
m.line_number,
self.delimiter,
escape_csv(&m.matched_text),
self.delimiter,
escape_csv(&m.line_content)
));
output.push('\n');
}
Ok(output)
}
fn format_results(&self, results: &[GrepResult]) -> Result<String> {
let mut output = String::new();
output.push_str(&format!(
"notebook{}cell_index{}cell_number{}execution_count{}match_type{}line_index{}line_number{}matched_text{}line_content\n",
self.delimiter, self.delimiter, self.delimiter, self.delimiter,
self.delimiter, self.delimiter, self.delimiter, self.delimiter
));
for result in results {
for m in &result.matches {
let exec_count = m.execution_count.map(|c| c.to_string()).unwrap_or_default();
output.push_str(&format!(
"\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"",
escape_csv(&result.notebook),
self.delimiter,
m.cell_index,
self.delimiter,
m.cell_number,
self.delimiter,
exec_count,
self.delimiter,
m.match_type,
self.delimiter,
m.line_index,
self.delimiter,
m.line_number,
self.delimiter,
escape_csv(&m.matched_text),
self.delimiter,
escape_csv(&m.line_content)
));
output.push('\n');
}
}
Ok(output)
}
}
fn escape_csv(s: &str) -> String {
s.replace('"', "\"\"")
}