ferric_ai/commands/
pretty_print.rs

1// Pretty-print command handler for displaying flamegraph call trees
2
3pub const PRETTY_PRINT_LONG_ABOUT: &str = "Display flamegraph call tree in human-readable hierarchical format for performance analysis. Outputs function names with CPU percentages, sample counts, and call depth indentation. Shows inclusive CPU time (function + children) and exclusive CPU time (function only). Useful for understanding call relationships, identifying performance bottlenecks, and visualizing program execution flow. Output format uses tree structure with indentation to represent call stack depth.";
4
5use crate::cli::Cli;
6use crate::error::Result;
7use crate::handler::CommandHandler;
8use crate::helpers::parse_trees_no_comparison;
9
10/// Handler for the pretty-print command
11///
12/// This command parses a flamegraph SVG file and displays the call tree
13/// in a human-readable hierarchical format with CPU percentages and sample counts.
14pub struct PrettyPrintHandler;
15
16impl CommandHandler for PrettyPrintHandler {
17    fn execute(&self, cli: &Cli) -> Result<()> {
18        // Use custom parsing that doesn't support comparison
19        let trees = parse_trees_no_comparison(cli)?;
20
21        // Handle trees based on count (zero case handled in main.rs)
22        match trees.len() {
23            1 => {
24                // Single tree - print without headers for clean output
25                println!("{}", trees[0]);
26            }
27            n => {
28                // Multiple trees - use LLM-friendly delimiters
29                for (i, tree) in trees.iter().enumerate() {
30                    println!("<!-- FLAMEGRAPH_TREE_START: Tree {} of {} -->", i + 1, n);
31                    println!("=== Tree {} ===", i + 1);
32                    println!("{}", tree);
33                    println!("<!-- FLAMEGRAPH_TREE_END: Tree {} of {} -->", i + 1, n);
34
35                    // Add separator between trees (except after the last one)
36                    if i < n - 1 {
37                        println!("\n{}\n", "─".repeat(80));
38                    }
39                }
40            }
41        }
42
43        Ok(())
44    }
45
46    // Override default parse_trees to disable comparison support
47    fn parse_trees(&self, cli: &Cli) -> Result<(Vec<crate::parser::Tree>, Vec<crate::parser::Tree>)> {
48        if cli.compare.is_some() {
49            return Err(crate::error::FerricError::CommandError(
50                "The pretty-print command does not support comparison mode (-c flag). Use this command with single files or directories only.".to_string()
51            ));
52        }
53
54        let trees = parse_trees_no_comparison(cli)?;
55        Ok((trees, Vec::new())) // No comparison trees
56    }
57}
58
59
60impl Default for PrettyPrintHandler {
61    fn default() -> Self {
62        Self
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_pretty_print_handler_creation() {
72        let _handler = PrettyPrintHandler;
73        // Just verify it can be created
74    }
75
76    #[test]
77    fn test_default_pretty_print_handler() {
78        let _handler = PrettyPrintHandler;
79        // Just verify it can be created with default
80    }
81}