Skip to main content

High-performance rule engine with MongoDB-style query syntax

Project description

fast-decision

Crates.io PyPI License

A high-performance rule engine written in Rust with Python bindings, designed for applications that need to evaluate complex business rules with minimal latency and maximum throughput.

Features

  • High Performance: Rust-powered engine with zero-cost abstractions
  • Priority-based Execution: Rules sorted by priority (lower number = higher priority)
  • Stop-on-First: Per-category flag to stop after first match
  • MongoDB-style Operators: Familiar syntax with $eq, $ne, $gt, $lt, $gte, $lte, $and, $or
  • Complex Logic: Support for nested AND/OR predicates
  • Python Bindings: Native performance with idiomatic Python API via PyO3
  • Memory Efficient: Minimal allocations in hot path, optimized data structures
  • Benchmarked: Built-in performance benchmarks with Criterion

Use Cases

  • Business rule engines
  • Dynamic pricing systems
  • Feature flags and A/B testing
  • Access control and authorization
  • Data validation and filtering
  • Workflow automation

Installation

Rust

Add to your Cargo.toml:

[dependencies]
fast-decision = "0.1"

Python

pip install fast-decision

Or install from source:

git clone https://github.com/almayce/fast-decision.git
cd fast-decision
maturin develop --release

Quick Start

Rust Example

use fast_decision::{RuleEngine, RuleSet};
use serde_json::json;

fn main() {
    let rules_json = r#"
    {
      "categories": {
        "Pricing": {
          "stop_on_first": true,
          "rules": [
            {
              "id": "Platinum_Discount",
              "priority": 1,
              "conditions": {"user.tier": {"$eq": "Platinum"}},
              "action": "apply_20_percent_discount"
            },
            {
              "id": "Gold_Discount",
              "priority": 10,
              "conditions": {"user.tier": {"$eq": "Gold"}},
              "action": "apply_10_percent_discount"
            }
          ]
        }
      }
    }
    "#;

    let ruleset: RuleSet = serde_json::from_str(rules_json).unwrap();
    let engine = RuleEngine::new(ruleset);

    let data = json!({
        "user": {"tier": "Gold", "id": 123},
        "transaction": {"amount": 100}
    });

    let results = engine.execute(&data, &["Pricing"]);
    println!("Triggered rules: {:?}", results);
    // Output: ["Gold_Discount"]
}

Python Example

See python/README.md for detailed Python documentation.

from fast_decision import FastDecision

# Load rules from JSON file
engine = FastDecision("rules.json")

# Execute rules
data = {
    "user": {"tier": "Gold", "id": 123},
    "transaction": {"amount": 100}
}

results = engine.execute(data, categories=["Pricing"])
print(f"Triggered rules: {results}")
# Output: ['Gold_Discount']

Rule Format

Rules are defined in JSON with MongoDB-style syntax:

{
  "categories": {
    "CategoryName": {
      "stop_on_first": true,
      "rules": [
        {
          "id": "rule_identifier",
          "priority": 1,
          "conditions": {
            "field.path": {"$eq": "value"}
          },
          "action": "action_name"
        }
      ]
    }
  }
}

Supported Operators

Operator Description Example
$eq Equal {"age": {"$eq": 18}}
$ne Not equal {"status": {"$ne": "inactive"}}
$gt Greater than {"score": {"$gt": 100}}
$lt Less than {"price": {"$lt": 50}}
$gte Greater than or equal {"age": {"$gte": 21}}
$lte Less than or equal {"count": {"$lte": 10}}

Logical Operators

Implicit AND - Multiple conditions in one object:

{
  "conditions": {
    "age": {"$gte": 18, "$lt": 65},
    "status": {"$eq": "active"}
  }
}

Explicit OR - Use $or:

{
  "conditions": {
    "$or": [
      {"tier": {"$eq": "Platinum"}},
      {"score": {"$gt": 1000}}
    ]
  }
}

Nested Logic:

{
  "conditions": {
    "$or": [
      {"tier": {"$eq": "Platinum"}},
      {
        "tier": {"$eq": "Gold"},
        "amount": {"$gt": 500}
      }
    ]
  }
}

Performance

Benchmarks

Run benchmarks:

cargo bench

Optimization Features

  • Rust backend: Native machine code performance
  • Zero allocations in hot execution path
  • Inline functions: Critical comparison functions marked #[inline(always)]
  • Optimized data structures: Box<[String]> for path tokens, #[repr(u8)] for operators
  • Pre-sorted rules: Rules sorted by priority at load time
  • Direct conversion: Python dict → Rust without intermediate JSON serialization
  • Link Time Optimization (LTO): Enabled in release profile

Performance Characteristics

  • Rule evaluation: O(n) where n = number of rules in requested categories
  • Field lookup: O(d) where d = depth of nested field path
  • Memory: Minimal allocations during execution (only for results)

Development

# Run tests
cargo test

# Run Rust examples
cargo run --example demo

# Run benchmarks
cargo bench

# Build documentation
cargo doc --no-deps --open

# Run Python tests
cd python/tests
python test_features.py

# Run Python examples
cd python/examples
python example.py

Contributing

See CONTRIBUTING.md for development guidelines.

Architecture

fast-decision/
├── src/              # Rust core engine
│   ├── lib.rs        # Python bindings (PyO3)
│   ├── engine.rs     # Rule execution engine
│   └── types.rs      # Data structures
├── benches/          # Performance benchmarks
├── examples/         # Rust examples
├── python/           # Python bindings and examples
│   ├── examples/     # Usage examples
│   └── tests/        # Tests
├── Cargo.toml        # Rust configuration
└── pyproject.toml    # Python packaging

License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fast_decision-0.1.2.tar.gz (33.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fast_decision-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl (277.6 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

File details

Details for the file fast_decision-0.1.2.tar.gz.

File metadata

  • Download URL: fast_decision-0.1.2.tar.gz
  • Upload date:
  • Size: 33.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.10.2

File hashes

Hashes for fast_decision-0.1.2.tar.gz
Algorithm Hash digest
SHA256 9ed78a5933fbd46e76ae3ff71f6d20e5862db2f8a4966a0f710c23646d7cb508
MD5 b8327fd0fee30a43dde990ccb158cc72
BLAKE2b-256 0b984c2a2a2839091bf3b09069dab697ba247073c920e74df3628c4bc9ee99f5

See more details on using hashes here.

File details

Details for the file fast_decision-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for fast_decision-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 0b246409890d6ddc2e64e75a3d5816e256f613bf93117c2f4151f5ac725e9bba
MD5 97a55fc3dd89a18fa93c98dfeba58b3f
BLAKE2b-256 30ac1639f97aa0610005ef112b07162cf54d9db20a971de2fad5958c389a0ccf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page