mod architecture;
mod boilerplate;
mod complexity;
mod coupling;
mod dry;
mod governance;
mod iosp;
mod srp;
mod structural;
mod tq;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RuleCard {
pub id: &'static str,
pub title: &'static str,
pub detects: &'static str,
pub why: &'static str,
pub fix: &'static str,
pub suppress: &'static str,
pub config: &'static str,
}
const GROUPS: &[&[RuleCard]] = &[
iosp::CARDS,
complexity::CARDS,
dry::CARDS,
boilerplate::CARDS,
srp::CARDS,
coupling::CARDS,
structural::CARDS,
tq::CARDS,
architecture::CARDS,
governance::CARDS,
];
pub fn all_rule_cards() -> impl Iterator<Item = &'static RuleCard> {
GROUPS.iter().flat_map(|g| g.iter())
}
pub fn find_rule_card(id: &str) -> Option<&'static RuleCard> {
id_prefixes(id).into_iter().find_map(|p| exact_card(p))
}
fn exact_card(id: &str) -> Option<&'static RuleCard> {
all_rule_cards().find(|c| c.id.eq_ignore_ascii_case(id))
}
fn id_prefixes(id: &str) -> Vec<&str> {
let mut ends: Vec<usize> = vec![id.len()];
ends.extend(id.match_indices('/').map(|(i, _)| i));
ends.sort_unstable_by(|a, b| b.cmp(a));
ends.into_iter().map(|e| &id[..e]).collect()
}