codelens_core/output/
html.rs1use std::io::Write;
4
5use askama::Template;
6
7use crate::analyzer::stats::{AnalysisResult, LanguageSummary, Summary};
8use crate::error::Result;
9
10use super::format::{OutputFormat, OutputOptions};
11
12#[derive(Template)]
14#[template(path = "report.html")]
15struct HtmlReport<'a> {
16 title: &'a str,
17 generated_at: String,
18 summary: &'a Summary,
19 by_language: Vec<(&'a str, &'a LanguageSummary)>,
20 elapsed_secs: f64,
21}
22
23pub struct HtmlOutput;
25
26impl HtmlOutput {
27 pub fn new() -> Self {
29 Self
30 }
31}
32
33impl Default for HtmlOutput {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38
39impl OutputFormat for HtmlOutput {
40 fn name(&self) -> &'static str {
41 "html"
42 }
43
44 fn extension(&self) -> &'static str {
45 "html"
46 }
47
48 fn write(
49 &self,
50 result: &AnalysisResult,
51 options: &OutputOptions,
52 writer: &mut dyn Write,
53 ) -> Result<()> {
54 let mut by_language: Vec<_> = result
55 .summary
56 .by_language
57 .iter()
58 .map(|(k, v)| (k.as_str(), v))
59 .collect();
60
61 if let Some(n) = options.top_n {
62 by_language.truncate(n);
63 }
64
65 let report = HtmlReport {
66 title: "Codelens - Code Statistics Report",
67 generated_at: chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
68 summary: &result.summary,
69 by_language,
70 elapsed_secs: result.elapsed.as_secs_f64(),
71 };
72
73 write!(writer, "{}", report.render()?)?;
74 Ok(())
75 }
76}