Expand description
§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.
§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
§Basic Usage
Here’s how to use Rusty Rules with a custom context type:
use std::collections::HashMap;
use std::net::IpAddr;
use rusty_rules::{Engine, Value};
use serde_json::json;
// 1. Define context type
struct MyContext {
method: String,
path: String,
headers: HashMap<String, String>,
addr: IpAddr,
}
// 2. Create a new engine
let mut engine = Engine::new();
// 3. Register fetchers to extract values from context
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(Value::Ip(ctx.addr))
});
// 4. Compile a rule from JSON
let rule = engine.compile_rule(&json!({
"all": [
{"method": "GET"},
{"header(host)": "www.example.com"},
{"addr": {"ip": ["10.0.0.0/8"]}}
]
})).unwrap();
// 5. Evaluate the rule against a context
let ctx = MyContext {
method: "GET".to_string(),
path: "/api/v1/users".to_string(),
headers: {
let mut h = HashMap::new();
h.insert("host".to_string(), "www.example.com".to_string());
h
},
addr: "10.1.2.3".parse().unwrap(),
};
assert!(rule.evaluate(&ctx).unwrap());
§Rule Composition
Rules can be composed using logical operators:
{
"all": [ // All conditions must match (logical AND)
{ "method": "GET" },
{ "path": { "regex": "^/api/v\\d+" } },
{
"any": [ // Any condition must match (logical OR)
{ "header(auth)": { "exists": true } },
{ "ip": { "cidr": "10.0.0.0/8" } }
]
},
{
"not": [ // Negate the condition (logical NOT)
{ "header(user-agent)": "BadBot/1.0" }
]
}
]
}
§Custom Operators
You can extend the engine with custom operators:
// Register a custom string prefix operator
engine.register_operator("starts_with", |value: JsonValue| {
let prefix = value.as_str().ok_or("prefix must be a string")?.to_string();
Ok(Operator::new(move |_, value| {
Ok(value.as_str()
.map(|s| s.starts_with(&prefix))
.unwrap_or_default())
}))
});
// Use the custom operator in a rule
let rule = engine.compile_rule(&json!({
"path": {
"starts_with": "/api/v1"
}
})).unwrap();
§JSON Schema Validation
With the validation
feature enabled, you can validate rules against a dynamically generated schema:
let rule = json!({
"all": [
{"method": "GET"},
{"path": {
"re": "^/api/v\\d+"
}}
]
});
// Validate the rule against the engine's schema
let result = engine.validate_rule(&rule);
§Feature Flags
- send - Enables
Send
andSync
trait bounds on all public types, making them safe to use across thread boundaries - validation - Enables JSON schema generation and validation functionality (adds
jsonschema
dependency)
Structs§
- Bool
Matcher - A matcher for boolean values.
- Default
Matcher - A flexible matcher without strict types.
- Engine
- Rules engine for registering fetchers/operators and parsing rules.
- Fetcher
- Holds a fetcher’s required matcher type and function.
- IpMatcher
- A matcher for IP subnets.
- Number
Matcher - A matcher for number values.
- Regex
Matcher - A matcher for string values with regular expressions by default.
- String
Matcher - A matcher for string values.
- Validation
Error validation
- An error that can occur during validation.
Enums§
- Error
- Represents possible errors that can occur during rules parsing.
- Operator
- Represents an operator that used to check if a fetched value satisfies the condition.
- Rule
- Represents a rule, which can be a condition or a logical combination of other rules.
- Value
- Represents possible values returned by fetchers
Traits§
- Matcher
- Trait for types matchers
- ToOperator
Type Aliases§
- Async
Check Fn - Callback type for async operator check function
- Async
Fetcher Fn - Callback type for async fetchers
- CheckFn
- Callback type for operator check function
- Fetcher
Fn - Callback type for fetchers