2 releases
new 0.1.1 | May 19, 2025 |
---|---|
0.1.0 | May 19, 2025 |
#2 in #overhead
89KB
1.5K
SLoC
rusty-rules
A blazingly fast, flexible, and extensible rules engine written in Rust. Evaluate complex logical rules against custom data structures using a simple JSON-based DSL. Supports both synchronous and asynchronous fetchers, custom operators, and a variety of matchers.
Features
- Composable rules: Combine conditions with
all
,any
, andnot
logical blocks for complex rule hierarchies - Custom fetchers: Extract values from data structures with named fetchers that accept arguments
- Matcher support: String, regex, IP address, numeric, and boolean matchers out of the box
- Custom operators: Define operators for advanced matching and domain-specific logic
- Async support: Register async fetchers and operators for use with async/await contexts
- JSON-schema validation: Validate rules with automatically generated JSON schema (requires
validation
feature) - Thread-safety option: Optional
Send
/Sync
trait bounds with thesend
feature flag - Performance-focused: Designed for high-throughput rule evaluation with minimal overhead
Installation
Add to Cargo.toml
:
[dependencies]
rusty-rules = "0.1"
Basic Usage
Define context
use std::collections::HashMap;
use std::net::IpAddr;
struct MyContext {
method: String,
path: String,
headers: HashMap<String, String>,
addr: IpAddr,
}
Register fetchers
use rusty_rules::{Engine, Value};
let mut engine = Engine::new();
engine.register_fetcher("method", |ctx: &MyContext, _args| {
Ok(Value::from(&ctx.method))
});
engine.register_fetcher("header", |ctx: &MyContext, args| {
Ok(args.first().and_then(|name| ctx.headers.get(name)).into())
});
engine.register_fetcher("addr", |ctx: &MyContext, _args| {
Ok(ctx.addr.into())
});
// ...register other fetchers...
Compile and evaluate a rule
use serde_json::json;
let rule = engine.compile_rule(&json!({
"method": "GET",
"header(host)": "www.example.com",
"addr": {
"ip": ["10.0.0.0/8"]
}
})).unwrap();
let ctx = /* MyContext instance */;
assert!(rule.evaluate(&ctx).unwrap());
Dependencies
~3–12MB
~118K SLoC