Skip to main content

RuleEngine

Struct RuleEngine 

Source
pub struct RuleEngine<M: PatternMatcher> { /* private fields */ }
Expand description

Rule engine for loading and evaluating rules

The engine is generic over the pattern matcher implementation, allowing different matching strategies to be used (regex, literal, etc.).

§Example

use skill_veil_core::rules::{default_external_rule_dirs, RuleEngine};
use skill_veil_core::adapters::{RegexPatternMatcher, StdFileSystemProvider};
use std::sync::Arc;

// Compose adapters at the application boundary; the engine receives
// them through the injected ports.
let fs = StdFileSystemProvider::new();
let runtime_dirs = default_external_rule_dirs();
let engine = RuleEngine::with_defaults_and_matcher(
    Arc::new(RegexPatternMatcher::new()),
    &fs,
    &runtime_dirs,
)
.unwrap();
assert!(engine.rule_count() > 0);

Implementations§

Source§

impl<M: PatternMatcher> RuleEngine<M>

Source

pub fn with_matcher(matcher: Arc<M>) -> Self

Create a new rule engine with a custom pattern matcher.

Source

pub fn set_checksum_policy(&mut self, policy: ChecksumPolicy)

Override the integrity verification policy for external rule pack bodies. See ChecksumPolicy for the three modes. Default is WarnOnMissing.

Source

pub fn set_strict_mode(&mut self, strict: bool)

Toggle strict mode. When enabled, loading an external pack with a duplicate rule id returns RuleError::DuplicateUserRule instead of emitting a tracing::warn!() and skipping.

Source

pub fn with_defaults_and_matcher<F: FileSystemProvider>( matcher: Arc<M>, runtime_overlay_fs: &F, runtime_overlay_dirs: &[PathBuf], ) -> Result<Self, RuleError>

Create a rule engine with built-in rules plus an optional runtime overlay loaded through the injected FileSystemProvider.

§Load order contract

Built-in rules are loaded first, runtime overrides second. The non-strict duplicate-skip means inverting the order would silently discard canonical detections.

§Hexagonal boundary

runtime_overlay_fs and runtime_overlay_dirs are injected so the domain layer never instantiates a concrete adapter. Production callers compose them in the application layer (typically Scanner::with_std_adapters) by pairing StdFileSystemProvider with default_external_rule_dirs().

Source

pub fn load_from_dir<F: FileSystemProvider>( &mut self, fs: &F, dir: impl AsRef<Path>, ) -> Result<(), RuleError>

Load rules from a directory through a FileSystemProvider. Going through the port preserves the hexagonal contract: this loader reads YAML rule packs from disk, but the domain layer never reaches std::fs directly.

Source

pub fn load_rules_file<F: FileSystemProvider>( &mut self, fs: &F, path: impl AsRef<Path>, ) -> Result<(), RuleError>

Load rules from a YAML file.

In strict mode (default — see RuleEngine.strict_mode doc-comment for rationale), an ID that collides with an already-loaded rule (built-in or earlier-loaded external) returns RuleError::DuplicateUserRule { id, path }. The pre-flight at the time of the round-5 strict-mode flip showed 0 collisions between the embedded builtin_rules.yaml and the rules/official/ packs.

Callers that intentionally want the legacy “warn-and-skip” behaviour (e.g. tooling that loads many overlapping experimental packs) must opt out via set_strict_mode(false).

Source

pub fn add_rule(&mut self, rule: Rule) -> Result<(), RuleError>

Add a single rule.

Skips the rule if one with the same ID already exists.

Source

pub fn rules(&self) -> Vec<&Rule>

Get all loaded rules.

Source

pub fn evaluate(&self, doc: &SkillDocument) -> Vec<Finding>

Evaluate all rules against a document.

Source

pub fn rule_count(&self) -> usize

Get rule count.

Source

pub fn test_rule( &self, rule_id: &str, content: &str, parser: &dyn MarkdownParser, ) -> Result<Vec<Finding>, RuleError>

Test a rule against sample content.

The caller injects the MarkdownParser adapter so the domain layer stays free of concrete adapter dependencies. Production callers in the CLI pass &PulldownMarkdownParser::new(); tests pass whichever parser their fixture exercises.

Auto Trait Implementations§

§

impl<M> Freeze for RuleEngine<M>

§

impl<M> !RefUnwindSafe for RuleEngine<M>

§

impl<M> Send for RuleEngine<M>

§

impl<M> Sync for RuleEngine<M>

§

impl<M> Unpin for RuleEngine<M>

§

impl<M> UnsafeUnpin for RuleEngine<M>

§

impl<M> !UnwindSafe for RuleEngine<M>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more