1use super::OutputFormatter;
4use crate::types::GrepResult;
5use anyhow::Result;
6
7pub struct CsvFormatter {
9 delimiter: char,
10}
11
12impl CsvFormatter {
13 pub fn new() -> Self {
14 Self { delimiter: ',' }
15 }
16
17 pub fn with_delimiter(delimiter: char) -> Self {
18 Self { delimiter }
19 }
20}
21
22impl Default for CsvFormatter {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl OutputFormatter for CsvFormatter {
29 fn format_result(&self, result: &GrepResult) -> Result<String> {
30 let mut output = String::new();
31
32 output.push_str(&format!(
34 "notebook{}cell_index{}cell_number{}execution_count{}match_type{}line_index{}line_number{}matched_text{}line_content\n",
35 self.delimiter, self.delimiter, self.delimiter, self.delimiter,
36 self.delimiter, self.delimiter, self.delimiter, self.delimiter
37 ));
38
39 for m in &result.matches {
41 let exec_count = m.execution_count.map(|c| c.to_string()).unwrap_or_default();
42
43 output.push_str(&format!(
44 "\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"",
45 escape_csv(&result.notebook),
46 self.delimiter,
47 m.cell_index,
48 self.delimiter,
49 m.cell_number,
50 self.delimiter,
51 exec_count,
52 self.delimiter,
53 m.match_type,
54 self.delimiter,
55 m.line_index,
56 self.delimiter,
57 m.line_number,
58 self.delimiter,
59 escape_csv(&m.matched_text),
60 self.delimiter,
61 escape_csv(&m.line_content)
62 ));
63 output.push('\n');
64 }
65
66 Ok(output)
67 }
68
69 fn format_results(&self, results: &[GrepResult]) -> Result<String> {
70 let mut output = String::new();
71
72 output.push_str(&format!(
74 "notebook{}cell_index{}cell_number{}execution_count{}match_type{}line_index{}line_number{}matched_text{}line_content\n",
75 self.delimiter, self.delimiter, self.delimiter, self.delimiter,
76 self.delimiter, self.delimiter, self.delimiter, self.delimiter
77 ));
78
79 for result in results {
81 for m in &result.matches {
82 let exec_count = m.execution_count.map(|c| c.to_string()).unwrap_or_default();
83
84 output.push_str(&format!(
85 "\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"{}{}{}{}{}\"{}\"{}\"{}\"",
86 escape_csv(&result.notebook),
87 self.delimiter,
88 m.cell_index,
89 self.delimiter,
90 m.cell_number,
91 self.delimiter,
92 exec_count,
93 self.delimiter,
94 m.match_type,
95 self.delimiter,
96 m.line_index,
97 self.delimiter,
98 m.line_number,
99 self.delimiter,
100 escape_csv(&m.matched_text),
101 self.delimiter,
102 escape_csv(&m.line_content)
103 ));
104 output.push('\n');
105 }
106 }
107
108 Ok(output)
109 }
110}
111
112fn escape_csv(s: &str) -> String {
114 s.replace('"', "\"\"")
115}