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§
fn id(&self) -> &str
fn level(&self) -> Level
fn evaluate(&self, ctx: &Context<'_>) -> Result<Vec<Violation>>
Provided Methods§
fn policy_url(&self) -> Option<&str>
Sourcefn git_tracked_mode(&self) -> GitTrackedMode
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.
Sourcefn wants_git_blame(&self) -> bool
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.
Sourcefn requires_full_index(&self) -> bool
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.
Sourcefn path_scope(&self) -> Option<&Scope>
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).
Sourcefn fixer(&self) -> Option<&dyn Fixer>
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.
Sourcefn as_per_file(&self) -> Option<&dyn PerFileRule>
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.