| Crates.io | rule_kit |
| lib.rs | rule_kit |
| version | 0.1.1 |
| created_at | 2025-06-10 06:42:54.29755+00 |
| updated_at | 2025-06-13 02:54:24.991554+00 |
| description | A fast, composable, and DSL-friendly rule engine kit for Rust. |
| homepage | |
| repository | https://github.com/jerry-maheswara-github/rule_kit |
| max_upload_size | |
| id | 1706711 |
| size | 39,134 |
A blazing-fast, composable, and DSL-friendly rule engine kit for Rust.
Define your rules. Plug your context (mutable or immutable). Let the engine do the rest.
Rule<T> for any context (mutable support)Define a context (e.g., a struct), implement Rule<T> with mutable apply, and plug it into RuleEngine:
use rule_kit::{Rule, RuleEngine};
use rule_kit::builder::RuleEngineBuilder;
use rule_kit::utils::PriorityOrder;
#[derive(Debug)]
struct Order {
pub total: f64,
pub discount: f64,
}
#[derive(Debug, Clone)]
enum OrderRule {
DiscountIfHighValue,
}
impl Rule<Order> for OrderRule {
type RuleError = ();
fn name(&self) -> &str {
match self {
OrderRule::DiscountIfHighValue => "DiscountIfHighValue",
}
}
fn priority(&self) -> u32 {
1
}
fn evaluate(&self, ctx: &Order) -> Result<bool, Self::RuleError> {
match self {
OrderRule::DiscountIfHighValue => Ok(ctx.total > 100.0),
}
}
/// Note: `apply` takes `&mut self` and `&mut ctx`, allowing rule and context mutation.
fn apply(&mut self, ctx: &mut Order) -> Result<(), Self::RuleError> {
match self {
OrderRule::DiscountIfHighValue => {
let discount = ctx.total * 0.10;
ctx.discount += discount;
Ok(())
}
}
}
fn before_apply(&self, ctx: &Order) {
println!("Checking order total: {}", ctx.total);
}
fn after_apply(&self, ctx: &Order) {
println!("Applied discount, new total discount: {}", ctx.discount);
}
}
fn main() {
let mut order = Order {
total: 150.0,
discount: 0.0,
};
let rules = vec![OrderRule::DiscountIfHighValue];
// Using RuleEngine directly; pass mutable reference to context
let mut engine = RuleEngine::new(rules.clone(), None);
engine.evaluate_all(&mut order).unwrap();
println!("Discount after RuleEngine: {:.2}", order.discount);
// Using builder (with priority); also requires mutable context
let mut order2 = Order {
total: 150.0,
discount: 0.0,
};
let mut engine_built = RuleEngineBuilder::new()
.with_rules(rules)
.priority_asc()
.build();
engine_built.evaluate_all(&mut order2).unwrap();
println!("Discount after RuleEngineBuilder: {:.2}", order2.discount);
}
rule_kit is designed to be:
You implement the Rule<T> trait for your domain, where apply can mutate both the rule instance and the context, enabling advanced scenarios like workflow progression, state updates, or side effects.
Licensed under:
Created and maintained by Jerry Maheswara
Feel free to reach out for suggestions, issues, or improvements!
This project is built with ❤️ using Rust — a systems programming language that is safe, fast, and concurrent. Rust is the perfect choice for building reliable and efficient applications.
Pull requests, issues, and feedback are welcome!
If you find this crate useful, give it a ⭐ and share it with others in the Rust community.