memscope_rs/cli/commands/
generate_report.rs1use clap::ArgMatches;
6use std::error::Error;
7
8pub fn run_generate_report(matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
10 let input_file = matches
11 .get_one::<String>("input")
12 .ok_or("Input file is required")?;
13 let output_file = matches
14 .get_one::<String>("output")
15 .ok_or("Output file is required")?;
16 let format = matches
17 .get_one::<String>("format")
18 .map(|s| s.as_str())
19 .unwrap_or("html");
20
21 println!("📊 Generating report...");
22 println!("Input file: {}", input_file);
23 println!("Output file: {}", output_file);
24 println!("Format: {}", format);
25
26 match format {
27 "html" => {
28 let default_template = "report_template.html".to_string();
29 embed_json_to_html(input_file, &default_template, output_file)?;
30 }
31 _ => {
32 return Err(format!("Unsupported format: {}", format).into());
33 }
34 }
35
36 Ok(())
37}
38
39fn _original_main() {
40 let args: Vec<String> = std::env::args().collect();
41
42 if args.len() < 2 {
43 _print_usage();
44 return;
45 }
46
47 match args[1].as_str() {
48 "template" => {
49 let default_output = "interactive_template.html".to_string();
50 let output = args.get(2).unwrap_or(&default_output);
51
52 if !std::path::Path::new("interactive_template.html").exists() {
54 eprintln!("❌ Source template 'interactive_template.html' not found!");
55 eprintln!("Please make sure the interactive_template.html file exists in the current directory.");
56 std::process::exit(1);
57 }
58
59 if let Err(e) = std::fs::copy("interactive_template.html", output) {
60 eprintln!("❌ Error creating template: {e}");
61 std::process::exit(1);
62 }
63 println!("✅ Created interactive template: {output}");
64 }
65 "generate" => {
66 if args.len() < 4 {
67 eprintln!(
68 "❌ Usage: generate_report generate <json_file> <output_file> [template_file]"
69 );
70 std::process::exit(1);
71 }
72
73 let json_file = &args[2];
74 let output_file = &args[3];
75 let default_template = "report_template.html".to_string();
76 let template_file = args.get(4).unwrap_or(&default_template);
77
78 if let Err(e) = embed_json_to_html(json_file, template_file, output_file) {
79 eprintln!("❌ Error generating report: {e}");
80 std::process::exit(1);
81 }
82 }
83 _ => {
84 _print_usage();
85 }
86 }
87}
88
89fn embed_json_to_html(
90 json_file: &str,
91 template_file: &str,
92 output_file: &str,
93) -> Result<(), Box<dyn std::error::Error>> {
94 let json_content = std::fs::read_to_string(json_file)?;
95
96 let template_content = std::fs::read_to_string(template_file)?;
97 let inline_script = format!(
98 r#"<script type="text/javascript">
99// Embedded JSON data for offline analysis
100window.EMBEDDED_MEMORY_DATA = {json_content};
101console.log('📊 Loaded embedded memory analysis data');
102</script>"#
103 );
104
105 let final_html = template_content.replace("<!-- DATA_INJECTION_POINT -->", &inline_script);
106
107 std::fs::write(output_file, final_html)?;
108
109 println!("✅ Generated self-contained HTML report: {output_file}");
110 Ok(())
111}
112
113fn _print_usage() {
114 println!("🔍 Memory Analysis Report Generator");
115 println!();
116 println!("Usage:");
117 println!(" generate_report template [output_file]");
118 println!(" Create a standalone HTML template");
119 println!();
120 println!(" generate_report generate <json_file> <output_file> [template_file]");
121 println!(" Generate a self-contained HTML report from JSON data");
122 println!();
123 println!("Examples:");
124 println!(" generate_report template report_template.html");
125 println!(" generate_report generate data.json report.html report_template.html");
126 println!();
127 println!("The generated report.html is completely self-contained and can be:");
128 println!(" ✅ Opened directly in any browser (no server needed)");
129 println!(" ✅ Shared via email or file transfer");
130 println!(" ✅ Archived for historical analysis");
131 println!(" ✅ Viewed offline without any dependencies");
132}