Skip to main content

mago_reporting/formatter/
mod.rs

1use std::io::Write;
2
3use mago_database::ReadDatabase;
4
5use crate::IssueCollection;
6use crate::Level;
7use crate::color::ColorChoice;
8use crate::error::ReportingError;
9
10pub mod ariadne;
11pub mod checkstyle;
12pub mod code_count;
13pub mod count;
14pub mod emacs;
15pub mod github;
16pub mod gitlab;
17pub mod json;
18pub mod medium;
19pub mod rich;
20pub mod sarif;
21pub mod short;
22pub mod utils;
23
24/// Configuration for formatters.
25#[derive(Debug, Clone)]
26pub struct FormatterConfig {
27    /// Choice for colorizing output.
28    pub color_choice: ColorChoice,
29    /// Whether to sort issues before formatting.
30    pub sort: bool,
31    /// Minimum report level (filter out lower severity issues).
32    pub minimum_level: Option<Level>,
33    /// Whether to filter to only fixable issues.
34    pub filter_fixable: bool,
35}
36
37/// Trait for formatting issues to a writer.
38pub trait Formatter {
39    /// Format issues and write them to the provided writer.
40    ///
41    /// # Arguments
42    ///
43    /// * `writer` - The writer to output formatted issues to
44    /// * `issues` - The collection of issues to format
45    /// * `database` - The read database for accessing source files
46    /// * `config` - Configuration for formatting behavior
47    ///
48    /// # Errors
49    ///
50    /// Returns an error if formatting or writing fails.
51    fn format(
52        &self,
53        writer: &mut dyn Write,
54        issues: &IssueCollection,
55        database: &ReadDatabase,
56        config: &FormatterConfig,
57    ) -> Result<(), ReportingError>;
58}
59
60/// The format to use for reporting.
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumString, strum::VariantNames, Default)]
62#[strum(serialize_all = "kebab-case")]
63pub enum ReportingFormat {
64    /// Rich diagnostic format with full context.
65    #[default]
66    Rich,
67    /// Medium diagnostic format with balanced context.
68    Medium,
69    /// Short diagnostic format with minimal context.
70    Short,
71    /// Ariadne diagnostic format.
72    Ariadne,
73    /// GitHub Actions format.
74    Github,
75    /// GitLab Code Quality format.
76    Gitlab,
77    /// JSON format.
78    Json,
79    /// Issue count by severity.
80    Count,
81    /// Issue count by code.
82    CodeCount,
83    /// Checkstyle XML format.
84    Checkstyle,
85    /// Emacs compilation mode format.
86    Emacs,
87    /// SARIF format (Static Analysis Results Interchange Format).
88    Sarif,
89}
90
91/// Dispatch to the appropriate formatter based on the format type.
92///
93/// This function performs static dispatch using enum matching for optimal performance.
94pub(crate) fn dispatch_format(
95    format: ReportingFormat,
96    writer: &mut dyn Write,
97    issues: &IssueCollection,
98    database: &ReadDatabase,
99    config: &FormatterConfig,
100) -> Result<(), ReportingError> {
101    match format {
102        ReportingFormat::Rich => rich::RichFormatter.format(writer, issues, database, config),
103        ReportingFormat::Medium => medium::MediumFormatter.format(writer, issues, database, config),
104        ReportingFormat::Short => short::ShortFormatter.format(writer, issues, database, config),
105        ReportingFormat::Ariadne => ariadne::AriadneFormatter.format(writer, issues, database, config),
106        ReportingFormat::Json => json::JsonFormatter.format(writer, issues, database, config),
107        ReportingFormat::Github => github::GithubFormatter.format(writer, issues, database, config),
108        ReportingFormat::Gitlab => gitlab::GitlabFormatter.format(writer, issues, database, config),
109        ReportingFormat::Checkstyle => checkstyle::CheckstyleFormatter.format(writer, issues, database, config),
110        ReportingFormat::Emacs => emacs::EmacsFormatter.format(writer, issues, database, config),
111        ReportingFormat::Count => count::CountFormatter.format(writer, issues, database, config),
112        ReportingFormat::CodeCount => code_count::CodeCountFormatter.format(writer, issues, database, config),
113        ReportingFormat::Sarif => sarif::SarifFormatter.format(writer, issues, database, config),
114    }
115}