mod text;
pub use text::*;
use crate::diagnostic::{render_help, HelpRenderTarget};
use crate::linter::LintResult;
use serde::Serialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum OutputFormat {
#[default]
Text,
Json,
}
pub fn format_results(
results: &[LintResult],
sources: &[(String, String)],
format: OutputFormat,
) -> String {
match format {
OutputFormat::Text => format_text(results, sources),
OutputFormat::Json => format_json(results),
}
}
#[derive(Debug, Serialize)]
pub struct JsonFileResult {
pub file: String,
pub messages: Vec<JsonMessage>,
#[serde(rename = "errorCount")]
pub error_count: usize,
#[serde(rename = "warningCount")]
pub warning_count: usize,
}
#[derive(Debug, Serialize)]
pub struct JsonMessage {
#[serde(rename = "ruleId")]
pub rule_id: &'static str,
pub severity: u8,
pub message: String,
pub line: u32,
pub column: u32,
#[serde(rename = "endLine")]
pub end_line: u32,
#[serde(rename = "endColumn")]
pub end_column: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub help: Option<String>,
}
fn format_json(results: &[LintResult]) -> String {
let json_results: Vec<JsonFileResult> = results
.iter()
.map(|r| JsonFileResult {
file: r.filename.clone(),
messages: r
.diagnostics
.iter()
.map(|d| {
JsonMessage {
rule_id: d.rule_name,
severity: match d.severity {
crate::diagnostic::Severity::Error => 2,
crate::diagnostic::Severity::Warning => 1,
},
message: d.formatted_message(),
line: 1, column: d.start + 1,
end_line: 1,
end_column: d.end + 1,
help: d
.help
.as_ref()
.map(|h| render_help(h, HelpRenderTarget::PlainText)),
}
})
.collect(),
error_count: r.error_count,
warning_count: r.warning_count,
})
.collect();
serde_json::to_string_pretty(&json_results).unwrap_or_else(|_| "[]".to_string())
}