use std::io::Write;
use mago_database::ReadDatabase;
use crate::IssueCollection;
use crate::Level;
use crate::baseline::Baseline;
use crate::color::ColorChoice;
use crate::error::ReportingError;
use crate::formatter::FormatterConfig;
use crate::formatter::ReportingFormat;
use crate::formatter::dispatch_format;
use crate::output::ReportingTarget;
#[derive(Debug)]
pub struct ReporterConfig {
pub target: ReportingTarget,
pub format: ReportingFormat,
pub color_choice: ColorChoice,
pub filter_fixable: bool,
pub sort: bool,
pub minimum_report_level: Option<Level>,
pub editor_url: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ReportStatus {
pub baseline_dead_issues: bool,
pub baseline_filtered_issues: usize,
pub highest_reported_level: Option<Level>,
pub lowest_reported_level: Option<Level>,
pub total_reported_issues: usize,
}
#[derive(Debug)]
pub struct Reporter {
database: ReadDatabase,
config: ReporterConfig,
}
impl Reporter {
#[must_use]
pub fn new(database: ReadDatabase, config: ReporterConfig) -> Self {
Self { database, config }
}
pub fn report(&self, issues: IssueCollection, baseline: Option<Baseline>) -> Result<ReportStatus, ReportingError> {
let mut writer = self.config.target.resolve();
let mut issues = issues;
let mut baseline_has_dead_issues = false;
let mut baseline_filtered_issues = 0;
if let Some(baseline) = baseline {
let original_count = issues.len();
let comparison = baseline.compare_with_issues(&issues, &self.database);
let filtered_issues = baseline.filter_issues(issues, &self.database);
baseline_filtered_issues = original_count - filtered_issues.len();
baseline_has_dead_issues = comparison.removed_issues_count > 0;
issues = filtered_issues;
}
let total_reported_issues = issues.len();
let highest_reported_level = issues.get_highest_level();
let lowest_reported_level = issues.get_lowest_level();
if total_reported_issues == 0 {
return Ok(ReportStatus {
baseline_dead_issues: baseline_has_dead_issues,
baseline_filtered_issues,
highest_reported_level: None,
lowest_reported_level: None,
total_reported_issues: 0,
});
}
let formatter_config = FormatterConfig {
color_choice: self.config.color_choice,
sort: self.config.sort,
minimum_level: self.config.minimum_report_level,
filter_fixable: self.config.filter_fixable,
editor_url: self.config.editor_url.clone(),
};
dispatch_format(self.config.format, &mut *writer, &issues, &self.database, &formatter_config)?;
writer.flush()?;
Ok(ReportStatus {
baseline_dead_issues: baseline_has_dead_issues,
baseline_filtered_issues,
highest_reported_level,
lowest_reported_level,
total_reported_issues,
})
}
pub fn report_to<W: Write>(
&self,
issues: IssueCollection,
baseline: Option<Baseline>,
writer: &mut W,
) -> Result<ReportStatus, ReportingError> {
let mut issues = issues;
let mut baseline_has_dead_issues = false;
let mut baseline_filtered_issues = 0;
if let Some(baseline) = baseline {
let original_count = issues.len();
let comparison = baseline.compare_with_issues(&issues, &self.database);
let filtered_issues = baseline.filter_issues(issues, &self.database);
baseline_filtered_issues = original_count - filtered_issues.len();
baseline_has_dead_issues = comparison.removed_issues_count > 0;
issues = filtered_issues;
}
let total_reported_issues = issues.len();
let highest_reported_level = issues.get_highest_level();
let lowest_reported_level = issues.get_lowest_level();
if total_reported_issues == 0 {
return Ok(ReportStatus {
baseline_dead_issues: baseline_has_dead_issues,
baseline_filtered_issues,
highest_reported_level: None,
lowest_reported_level: None,
total_reported_issues: 0,
});
}
let formatter_config = FormatterConfig {
color_choice: self.config.color_choice,
sort: self.config.sort,
minimum_level: self.config.minimum_report_level,
filter_fixable: self.config.filter_fixable,
editor_url: self.config.editor_url.clone(),
};
dispatch_format(self.config.format, writer, &issues, &self.database, &formatter_config)?;
Ok(ReportStatus {
baseline_dead_issues: baseline_has_dead_issues,
baseline_filtered_issues,
highest_reported_level,
lowest_reported_level,
total_reported_issues,
})
}
}