mod absolute_filesystem_paths;
mod absolute_module_paths;
mod banned_dependencies;
mod duplicate_logic;
mod duplicate_types_alias;
mod file_complexity;
mod layer_direction;
mod public_api_errors;
mod srp_heuristic;
mod use_tree_path;
use crate::analysis::Workspace;
use crate::config::{Level, Policy, RuleSettings};
use crate::emit::Emitter;
use crate::report::RuleCatalogEntry;
pub use absolute_filesystem_paths::AbsoluteFilesystemPathsRule;
pub use absolute_module_paths::AbsoluteModulePathsRule;
pub use banned_dependencies::BannedDependenciesRule;
pub use duplicate_logic::DuplicateLogicRule;
pub use duplicate_types_alias::DuplicateTypesAliasCandidateRule;
pub use file_complexity::FileComplexityRule;
pub use layer_direction::LayerDirectionRule;
pub use public_api_errors::PublicApiErrorsRule;
pub use srp_heuristic::SrpHeuristicRule;
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RuleFamily {
Architecture,
Design,
Shape,
Portability,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RuleBackend {
Syntax,
Semantic,
Adapter,
}
#[derive(Debug, Clone, Copy)]
pub struct RuleInfo {
pub id: &'static str,
pub family: RuleFamily,
pub backend: RuleBackend,
pub summary: &'static str,
pub default_level: Level,
pub schema: &'static str,
pub config_example: &'static str,
pub fixable: bool,
}
pub struct RuleContext<'a> {
pub policy: &'a Policy,
}
pub trait Rule {
fn info(&self) -> RuleInfo;
fn run(&self, ws: &Workspace, ctx: &RuleContext<'_>, out: &mut dyn Emitter);
}
fn all_rules() -> Vec<Box<dyn Rule>> {
vec![
Box::new(AbsoluteModulePathsRule),
Box::new(AbsoluteFilesystemPathsRule),
Box::new(FileComplexityRule),
Box::new(DuplicateLogicRule),
Box::new(DuplicateTypesAliasCandidateRule),
Box::new(SrpHeuristicRule),
Box::new(BannedDependenciesRule),
Box::new(PublicApiErrorsRule),
Box::new(LayerDirectionRule),
]
}
pub fn rule_catalog() -> Vec<RuleInfo> {
all_rules().into_iter().map(|rule| rule.info()).collect()
}
pub fn rule_catalog_entries() -> Vec<RuleCatalogEntry> {
rule_catalog()
.into_iter()
.map(|info| RuleCatalogEntry {
id: info.id.to_string(),
family: info.family,
backend: info.backend,
default_level: info.default_level,
summary: info.summary.to_string(),
fixable: info.fixable,
})
.collect()
}
pub fn enabled_rules(policy: &Policy) -> Vec<Box<dyn Rule>> {
all_rules()
.into_iter()
.filter(|rule| {
let info = rule.info();
policy.rule_enabled_anywhere(info.id, info.default_level)
})
.collect()
}
pub fn default_rule_settings() -> Vec<(String, RuleSettings)> {
rule_catalog()
.into_iter()
.map(|info| {
(
info.id.to_string(),
RuleSettings {
level: Some(info.default_level),
options: toml::Table::new(),
},
)
})
.collect()
}