use crate::reporting::output_format::OutputFormat;
use crate::reporting::rule_explanation::RuleExplanation;
use serde_json::Value;
use serde_json::json;
use serde_json::to_string_pretty;
pub struct RuleListing<'a> {
explanations: &'a [RuleExplanation],
}
impl<'a> RuleListing<'a> {
pub fn new(explanations: &'a [RuleExplanation]) -> Self {
Self { explanations }
}
pub fn render(&self, format: OutputFormat) -> String {
match format {
OutputFormat::Json => self.json(),
OutputFormat::Text => self.text(),
}
}
fn text(&self) -> String {
let mut out = String::from(
"stern4rust rules
",
);
for entry in self.explanations {
out.push_str(&format!(
"
{}
{}
",
entry.name, entry.summary
));
out.push_str(&Self::block("breaks", entry.breaks));
out.push_str(&Self::block("instead", entry.instead));
}
out
}
fn json(&self) -> String {
let entries: Vec<Value> = self
.explanations
.iter()
.map(|entry| {
json!({
"name": entry.name,
"summary": entry.summary,
"breaks": entry.breaks,
"instead": entry.instead,
})
})
.collect();
to_string_pretty(&json!({ "rules": entries }))
.unwrap_or_else(|_| String::from("{\"rules\":[]}"))
}
fn block(label: &str, body: &str) -> String {
let mut out = format!(
"
{label}:
"
);
for line in body.lines() {
out.push_str(&format!(
" {line}
"
));
}
out
}
}