This repository has been archived on 2026-08-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
el-retired/crates/el-arch/src/rule.rs
T

57 lines
2.2 KiB
Rust

//! Core trait and context types for architectural rules.
use std::collections::HashMap;
use crate::error::ArchDiagnostic;
/// Information about a single function call within a function body.
#[derive(Debug, Clone)]
pub struct CallInfo {
/// The name of the function being called.
pub callee: String,
/// True if this call appears inside a loop body (for or while).
pub is_in_loop: bool,
}
/// Full context about a single function being checked by arch rules.
pub struct FnContext<'a> {
/// Name of the function under analysis.
pub fn_name: &'a str,
/// Decorator names applied directly to this function (e.g. "accessor", "public").
pub annotations: &'a [String],
/// All calls made from within this function body.
pub body_calls: &'a [CallInfo],
/// Global map of function name → decorator names for the whole program.
pub all_fn_annotations: &'a HashMap<String, Vec<String>>,
/// TypeNames that appear in `activate TypeName where ...` calls in this function.
pub activate_types: &'a [String],
/// Whether this function contains a `sealed { }` block inside a loop.
pub has_sealed_in_loop: bool,
/// The return type of the function as a string (e.g. "Result", "Void", "String").
pub return_type_name: &'a str,
}
impl<'a> FnContext<'a> {
/// Returns true if this function has the given annotation/decorator.
pub fn has_annotation(&self, name: &str) -> bool {
self.annotations.iter().any(|a| a == name)
}
/// Returns true if the named callee has the given annotation in the program.
pub fn callee_has_annotation(&self, callee: &str, ann: &str) -> bool {
self.all_fn_annotations
.get(callee)
.map(|anns| anns.iter().any(|a| a == ann))
.unwrap_or(false)
}
}
/// An architectural rule that can be checked against a function context.
pub trait ArchRule: Send + Sync {
/// Short unique identifier, e.g. "VBD-001".
fn name(&self) -> &str;
/// Human-readable description of what this rule enforces.
fn description(&self) -> &str;
/// Run the rule against a function context, returning any diagnostics.
fn check(&self, ctx: &FnContext<'_>) -> Vec<ArchDiagnostic>;
}