jtool-grep 0.2.0

notebook-specific grep tool for jtool
Documentation
//! Template-based output formatter

use super::OutputFormatter;
use crate::types::{GrepResult, Match};
use anyhow::Result;

/// Template-based output formatter
pub struct TemplateFormatter {
    template: String,
}

impl TemplateFormatter {
    pub fn new(template: String) -> Self {
        Self { template }
    }

    /// Format a single match using the template
    fn format_match(&self, notebook: &str, m: &Match) -> String {
        let exec_str = if let Some(count) = m.execution_count {
            count.to_string()
        } else {
            String::new()
        };

        // Replace placeholders in the template
        self.template
            .replace("{notebook}", notebook)
            .replace("{cell}", &m.cell_index.to_string())
            .replace("{cell_num}", &m.cell_number.to_string())
            .replace("{exec}", &exec_str)
            .replace("{type}", &m.match_type.to_string())
            .replace("{line}", &m.line_index.to_string())
            .replace("{line_num}", &m.line_number.to_string())
            .replace("{match}", &m.matched_text)
            .replace("{full_line}", m.line_content.trim())
    }
}

impl OutputFormatter for TemplateFormatter {
    fn format_result(&self, result: &GrepResult) -> Result<String> {
        let mut output = String::new();

        for m in &result.matches {
            output.push_str(&self.format_match(&result.notebook, m));
            output.push('\n');
        }

        Ok(output)
    }

    fn format_results(&self, results: &[GrepResult]) -> Result<String> {
        let mut output = String::new();

        for result in results {
            output.push_str(&self.format_result(result)?);
        }

        Ok(output)
    }
}