Skip to main content

Rule

Trait Rule 

Source
pub trait Rule:
    Send
    + Sync
    + Debug {
    // Required methods
    fn id(&self) -> &str;
    fn level(&self) -> Level;
    fn evaluate(&self, ctx: &Context<'_>) -> Result<Vec<Violation>>;

    // Provided methods
    fn policy_url(&self) -> Option<&str> { ... }
    fn git_tracked_mode(&self) -> GitTrackedMode { ... }
    fn wants_git_blame(&self) -> bool { ... }
    fn requires_full_index(&self) -> bool { ... }
    fn path_scope(&self) -> Option<&Scope> { ... }
    fn fixer(&self) -> Option<&dyn Fixer> { ... }
    fn as_per_file(&self) -> Option<&dyn PerFileRule> { ... }
}
Expand description

Trait every built-in and plugin rule implements.

Required Methods§

Source

fn id(&self) -> &str

Source

fn level(&self) -> Level

Source

fn evaluate(&self, ctx: &Context<'_>) -> Result<Vec<Violation>>

Provided Methods§

Source

fn policy_url(&self) -> Option<&str>

Source

fn git_tracked_mode(&self) -> GitTrackedMode

Whether (and how) this rule narrows its iteration to git-tracked entries. Default GitTrackedMode::Off. Rule kinds that support git_tracked_only: override to return GitTrackedMode::FileOnly (file-mode rules: check set.contains(path)) or GitTrackedMode::DirAware (dir-mode rules: check dir_has_tracked_files(path, set)) when the user opts in.

The engine collects the tracked-paths set (via git ls-files) once per run when ANY rule returns a non-Off mode, then builds a pre-filtered FileIndex for each mode and routes opted-in rules to the right Context. Rules iterate ctx.index.files() / ctx.index.dirs() exactly as before — the index is already narrowed, so no per-rule if self.git_tracked_only && !ctx.is_git_tracked(...) runtime check is needed. Closes the same recurrence-risk shape as v0.9.10’s Scope-owns-scope_filter fix: docs/design/v0.9/git-tracked-filtered-index.md.

Source

fn wants_git_blame(&self) -> bool

Whether this rule needs git blame output on Context. Default false; the git_blame_age rule kind overrides to return true. The engine builds the shared crate::git::BlameCache once per run when any rule opts in, so multiple blame-aware rules over overlapping paths: re-use the parsed result.

Source

fn requires_full_index(&self) -> bool

In --changed mode, return true to evaluate this rule against the full FileIndex rather than the changed-only filtered subset. Default false (per-file semantics — the rule sees only changed files in scope).

Cross-file rules (pair, for_each_dir, every_matching_has, unique_by, dir_contains, dir_only_contains) override to true because their inputs span the whole tree by definition — a verdict on the changed file depends on what’s still in the rest of the tree. Existence rules (file_exists, file_absent, dir_exists, dir_absent) likewise consult the whole tree to answer “is X present?” correctly.

Source

fn path_scope(&self) -> Option<&Scope>

In --changed mode, return the Scope this rule is scoped to (typically the rule’s paths: field). The engine intersects the scope with the changed-set; rules whose scope doesn’t intersect are skipped, which is the optimisation --changed exists for.

Default None (“no scope information”) means the rule is always evaluated. Cross-file rules deliberately leave this as None (they always evaluate per the roadmap contract). Per-file rules with a single Scope field should override to return Some(&self.scope).

Source

fn fixer(&self) -> Option<&dyn Fixer>

Optional automatic-fix strategy. Rules whose violations can be mechanically corrected (e.g. creating a missing file, removing a forbidden one, renaming to the correct case) return a Fixer here; the default implementation reports the rule as unfixable.

Source

fn as_per_file(&self) -> Option<&dyn PerFileRule>

Opt into the file-major dispatch path. Per-file rules that can evaluate one file at a time given a pre-loaded byte slice override this to return Some(self); cross-file rules and any rule with requires_full_index() == true leave it as None and keep evaluating under the rule- major loop.

When the engine has multiple per-file rules sharing one scope, the file-major loop reads each matched file once and dispatches to every applicable per-file rule against the same byte buffer — coalescing N reads of one file into 1.

Implementors§