use std::path::Path;
use crate::linter::diagnostic::{Diagnostic, Severity};
use crate::syntax::SyntaxNode;
pub struct RuleContext<'a> {
pub path: Option<&'a Path>,
pub root: &'a SyntaxNode,
}
pub trait Rule: Send + Sync {
fn id(&self) -> &'static str;
fn default_severity(&self) -> Severity {
Severity::Warning
}
fn default_enabled(&self) -> bool {
true
}
fn run(&self, ctx: &RuleContext<'_>) -> Vec<Diagnostic>;
}
pub fn all_rules() -> Vec<Box<dyn Rule>> {
Vec::new()
}
pub struct ResolvedRules {
rules: Vec<Box<dyn Rule>>,
}
impl ResolvedRules {
pub fn resolve(select: Option<&[String]>, ignore: &[String]) -> Self {
let rules = all_rules()
.into_iter()
.filter(|rule| {
let enabled = match select {
Some(selected) => selected.iter().any(|id| id == rule.id()),
None => rule.default_enabled(),
};
enabled && !ignore.iter().any(|id| id == rule.id())
})
.collect();
Self { rules }
}
pub fn run(&self, ctx: &RuleContext<'_>) -> Vec<Diagnostic> {
self.rules.iter().flat_map(|rule| rule.run(ctx)).collect()
}
pub fn is_empty(&self) -> bool {
self.rules.is_empty()
}
}