infrastructure tier

infrastructure-rules-engine

Generic condition-DSL rule evaluator: JSON-record match/action model, an in-memory evaluator, and a field-mapped SQL WHERE-clause compiler

Generic condition-DSL rule evaluator: JSON-record match/action model, an in-memory evaluator, and a field-mapped SQL WHERE-clause compiler

Tierinfrastructure
Roleunclassified (baselined)
Pathcrates/infrastructure/rules-engine
Edition2021
Targetsinfrastructure_rules_engine
Public items16 across 3 modules
Tests33

What it is for

# infrastructure-rules-engine

A generic condition-DSL rule evaluator: a JSON-serializable match/action model (dsl), an in-memory evaluator over arbitrary serde_json::Value records (engine), and a field-mapped SQL WHERE-clause compiler for pushing the same conditions into Postgres (sql).

Sprint 3.45 crate 8 (docs/userstories/sprint-3.45-mail-manager-harvest.md). Source: rust-gmail-manager/src/rules_engine/{engine,dsl,sql_runner}.rs (Gate 4.5 provenance — see CHANGELOG.md for the per-module deviation notes, including why Eq's SQL compilation was corrected rather than carried forward as-is).

Deliberately generic — no mail-specific assumption survives

The source's EmailRow/gmail_labels/from.domain field-name allowlist is gone. This crate knows nothing about mail: Condition::field is an opaque dot-path into whatever JSON record the caller evaluates against, and Action::action is an opaque verb the caller defines and interprets. A tools-mail-manager consumer supplies its own field names ("from.domain", "subject", ...) and its own action vocabulary ("tag", "archive", ...) as plain strings/JSON — this crate imposes neither.

What was read but deliberately not ported: rules.rs

The sprint doc's source list for this crate also names rust-gmail-manager/src/rules.rs. That file's plan_actions/ execute_actions/execute_single/ActionType (Label/Archive/ Reply/Calendar/Flag/Trash) plan and execute actions by calling infrastructure_adapters_google_gmail::GmailClient::modify_labels/trash_message directly against a Gmail-shaped crate::mime::Email and an AI Classification. That is Gmail-adapter action execution, not condition-DSL evaluation — the two are different concerns bundled together in the source under one module path. Porting it here would mean either (a) inventing a generic ActionExecutor trait with no second consumer to ratify its shape (against Gate 4.5's first-consumer rule, and the sprint doc's own repeated non-goal philosophy — workflows/*, ml/*, web/handlers.rs are all deferred for exactly this reason), or (b) pulling a live infrastructure_adapters_google_gmail::GmailClient dependency into an infrastructure-layer crate that is otherwise dependency-free (violates AC-generic and this crate's whole reason for existing). Left for the tools-mail-manager tool (crate 11) to compose directly: read this crate's dsl::Action list off a matched rule, execute it however the target backend requires.

Capabilities

Action

The rule DSL's wire model: match conditions plus the actions a matching

Item
pub struct Action

Condition

The rule DSL's wire model: match conditions plus the actions a matching

Item
pub struct Condition

MatchBlock

The rule DSL's wire model: match conditions plus the actions a matching

Item
pub struct MatchBlock

MatchLogic

The rule DSL's wire model: match conditions plus the actions a matching

Item
pub enum MatchLogic

Operator

The rule DSL's wire model: match conditions plus the actions a matching

Item
pub enum Operator

RuleDsl

The rule DSL's wire model: match conditions plus the actions a matching

Item
pub struct RuleDsl
RuleDsl :: fn validate(& self) -> Result <(), String>

ConditionResult

In-memory rule evaluation over an arbitrary JSON record.

Item
pub struct ConditionResult
fn evaluate_rule(dsl : & RuleDsl, record : & serde_json::Value) ->(bool, Vec <ConditionResult>)

sql (other)

Compile a rule's conditions into a parameterized SQL WHERE-clause

Item
fn compile_where(dsl : & RuleDsl, columns : & ColumnMap) -> Option <CompiledWhere>
fn compile_where_from(dsl : & RuleDsl, columns : & ColumnMap, start : usize,) -> Option <CompiledWhere>

ColumnMap

Compile a rule's conditions into a parameterized SQL WHERE-clause

Item
pub struct ColumnMap
ColumnMap :: fn new() -> Self
ColumnMap :: fn with(mut self, field : impl Into <String>, column : impl Into <String>) -> Self
ColumnMap :: fn column_for(& self, field : & str) -> Option <& str>

CompiledWhere

Compile a rule's conditions into a parameterized SQL WHERE-clause

Item
pub struct CompiledWhere

How to use it

No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.

Module structure

infrastructure_rules_engine

flowchart TD
  n_infrastructure_rules_engine["infrastructure_rules_engine"]
  n_infrastructure_rules_engine --> n_dsl["dsl"]
  n_infrastructure_rules_engine --> n_engine["engine"]
  n_infrastructure_rules_engine --> n_sql["sql"]

Public surface

`dsl`

ItemWhat it is
pub struct RuleDslOne rule: a match expression plus the actions to fire when it matches.
pub struct MatchBlockA set of conditions joined by MatchLogic.
pub enum MatchLogicHow a MatchBlock's conditions combine.
pub struct ConditionOne condition: a field path, an operator, and (except for Operator::Exists) the value to compare against.
pub enum OperatorA condition operator
pub struct ActionOne action a matching rule fires
RuleDsl :: fn validate(& self) -> Result <(), String>Structural validation only: at least one condition, at least one action, no blank field/action names, and every non-Exists operator carries a value

`engine`

ItemWhat it is
pub struct ConditionResultThe per-condition outcome from evaluate_rule, useful for explaining why a rule did or didn't match.
fn evaluate_rule(dsl : & RuleDsl, record : & serde_json::Value) ->(bool, Vec <ConditionResult>)Evaluate whether record matches dsl's conditions, returning the overall verdict plus a per-condition breakdown.

`sql`

ItemWhat it is
pub struct ColumnMapA caller-supplied mapping from DSL field name to a trusted SQL column expression, e.g
ColumnMap :: fn new() -> Self
ColumnMap :: fn with(mut self, field : impl Into <String>, column : impl Into <String>) -> SelfRegister a field -> column mapping, builder-style.
ColumnMap :: fn column_for(& self, field : & str) -> Option <& str>
pub struct CompiledWhereA compiled WHERE-clause fragment: sql uses $N placeholders and params holds the bind values in the matching order.
fn compile_where(dsl : & RuleDsl, columns : & ColumnMap) -> Option <CompiledWhere>Compile dsl's conditions into a WHERE-clause fragment, placeholders starting at $1
fn compile_where_from(dsl : & RuleDsl, columns : & ColumnMap, start : usize,) -> Option <CompiledWhere>Same as compile_where, but placeholders start at start — for splicing into a query that already bound $1..=$(start - 1) itself (e.g

Re-exports. Exported here, defined elsewhere.

ExportDefined in
{Action,Condition,MatchBlock,MatchLogic,Operator,RuleDsl}dsl::{Action,Condition,MatchBlock,MatchLogic,Operator,RuleDsl}
{compile_where,compile_where_from,ColumnMap,CompiledWhere}sql::{compile_where,compile_where_from,ColumnMap,CompiledWhere}
{evaluate_rule,ConditionResult}engine::{evaluate_rule,ConditionResult}

Boundary

Depends on no other workspace tier.

Shares tier infrastructure with 82 other crates: infrastructure-acquire, infrastructure-adapters-google-calendar, infrastructure-adapters-google-gmail, infrastructure-adapters-google-places, infrastructure-adapters-google-trends, infrastructure-adapters-shodan, infrastructure-adapters-yelp, infrastructure-agent, … (82 total).

_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._

Where it sits

Tier (ontology)infrastructure
Architectural role (taxonomy)unclassified (baselined)
Locationcrates/infrastructure/rules-engine
Vocabulary in force (lexicon)current

Dependencies

Runtime, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
regex^1noalways
serde^1derivenoalways
serde_json^1noalways

Development. None.

Build. None.

Depended on by. Nothing in this workspace.

Feature flags

No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.

Targets

KindNameSource
libinfrastructure_rules_engine`src/lib.rs`

Error model

No public error type was detected: no public item declares a type named *Error, and no public signature returns one.

Operational characteristics

PropertyEvidence
async public surfacenone detected
async runtimenone detected
database accessnone detected
network I/Onone detected
unsafe codenone detected
environment variablesnone detected

No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.

Configuration

No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.

No workspace crate depends on this one.

Verification

KindCount
Unit tests33
Integration tests0
Examples0
Doctests0

Evidence by module. How often each public module is named by something executable.

ModuleTestsExamplesConsumers
dsl600
engine200
sql400

What the tests establish, by name:

Documentation coverage

MeasureDocumentedTotal
Public items with rustdoc1416
Public modules with a //! block33
pie showData
    title Public items with rustdoc
    "Documented" : 14
    "No rustdoc detected" : 2

Metrics

MetricValue
Rust source files4
Source lines949
Code lines698
Public API items16
Public modules3
Tests33
Examples0
Cargo features0
Direct runtime dependencies3
Workspace reverse dependencies0
pie showData
    title Public API by kind
    "enum" : 2
    "function" : 3
    "method" : 4
    "struct" : 7
pie showData
    title Rust source composition
    "Code" : 698
    "Blank or comment" : 251

Generation

Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.

All infrastructure · Manual