xbp-analysis 10.57.0

Language-agnostic static analysis (error-handling / Aspirator-style) for XBP
Documentation
//! Rule metadata and evaluation interface (domain-facing).

use super::capabilities::CapabilitySet;
use super::model::LanguageModel;
use super::types::{Finding, Severity};
use serde::{Deserialize, Serialize};

/// Static rule descriptor (language-independent catalog entry).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuleMeta {
    pub id: String,
    pub name: String,
    pub description: String,
    pub default_severity: Severity,
    /// Capabilities required; if missing, the rule is skipped (graceful degrade).
    pub required_capabilities: CapabilitySet,
    /// Whether an autofix may ever be offered (still subject to safety policy).
    pub autofix_safe: bool,
}

/// A rule that evaluates a language-independent model.
pub trait Rule: Send + Sync {
    fn meta(&self) -> &RuleMeta;
    fn evaluate(&self, model: &LanguageModel) -> Vec<Finding>;
}

/// Selection / filter for rules.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct RuleSelection {
    pub enabled: Vec<String>,
    pub disabled: Vec<String>,
    pub min_severity: Option<Severity>,
}

impl RuleSelection {
    pub fn allows(&self, rule_id: &str) -> bool {
        if self.disabled.iter().any(|d| d == rule_id || d == "*") {
            return false;
        }
        if self.enabled.is_empty() {
            return true;
        }
        self.enabled.iter().any(|e| e == rule_id || e == "*")
    }
}