Skip to main content

jtool_grep/output/
json.rs

1//! JSON output formatter
2
3use super::{OutputFormatter, OutputOptions};
4use crate::types::GrepResult;
5use anyhow::Result;
6use serde_json::json;
7
8/// JSON output formatter
9pub struct JsonFormatter {
10    options: OutputOptions,
11}
12
13impl JsonFormatter {
14    pub fn new(options: OutputOptions) -> Self {
15        Self { options }
16    }
17}
18
19impl Default for JsonFormatter {
20    fn default() -> Self {
21        Self::new(OutputOptions::default())
22    }
23}
24
25impl OutputFormatter for JsonFormatter {
26    fn format_result(&self, result: &GrepResult) -> Result<String> {
27        if self.options.count_mode {
28            let output = json!({
29                "notebook": result.notebook,
30                "count": result.matches.len(),
31            });
32            Ok(serde_json::to_string_pretty(&output)?)
33        } else {
34            let output = json!({
35                "notebook": result.notebook,
36                "matches": result.matches,
37                "total": result.matches.len(),
38            });
39            Ok(serde_json::to_string_pretty(&output)?)
40        }
41    }
42
43    fn format_results(&self, results: &[GrepResult]) -> Result<String> {
44        let total_matches: usize = results.iter().map(|r| r.matches.len()).sum();
45
46        if self.options.count_mode {
47            let counts: Vec<_> = results
48                .iter()
49                .map(|r| {
50                    json!({
51                        "notebook": r.notebook,
52                        "count": r.matches.len(),
53                    })
54                })
55                .collect();
56
57            let output = json!({
58                "counts": counts,
59                "total_notebooks": results.len(),
60                "total_matches": total_matches,
61            });
62            Ok(serde_json::to_string_pretty(&output)?)
63        } else {
64            let output = json!({
65                "results": results,
66                "total_notebooks": results.len(),
67                "total_matches": total_matches,
68            });
69            Ok(serde_json::to_string_pretty(&output)?)
70        }
71    }
72}