Skip to main content

jtool_grep/output/
template.rs

1//! Template-based output formatter
2
3use super::OutputFormatter;
4use crate::types::{GrepResult, Match};
5use anyhow::Result;
6
7/// Template-based output formatter
8pub struct TemplateFormatter {
9    template: String,
10}
11
12impl TemplateFormatter {
13    pub fn new(template: String) -> Self {
14        Self { template }
15    }
16
17    /// Format a single match using the template
18    fn format_match(&self, notebook: &str, m: &Match) -> String {
19        let exec_str = if let Some(count) = m.execution_count {
20            count.to_string()
21        } else {
22            String::new()
23        };
24
25        // Replace placeholders in the template
26        self.template
27            .replace("{notebook}", notebook)
28            .replace("{cell}", &m.cell_index.to_string())
29            .replace("{cell_num}", &m.cell_number.to_string())
30            .replace("{exec}", &exec_str)
31            .replace("{type}", &m.match_type.to_string())
32            .replace("{line}", &m.line_index.to_string())
33            .replace("{line_num}", &m.line_number.to_string())
34            .replace("{match}", &m.matched_text)
35            .replace("{full_line}", m.line_content.trim())
36    }
37}
38
39impl OutputFormatter for TemplateFormatter {
40    fn format_result(&self, result: &GrepResult) -> Result<String> {
41        let mut output = String::new();
42
43        for m in &result.matches {
44            output.push_str(&self.format_match(&result.notebook, m));
45            output.push('\n');
46        }
47
48        Ok(output)
49    }
50
51    fn format_results(&self, results: &[GrepResult]) -> Result<String> {
52        let mut output = String::new();
53
54        for result in results {
55            output.push_str(&self.format_result(result)?);
56        }
57
58        Ok(output)
59    }
60}