Complete guide to the plugin system in rust-rule-engine.
The plugin system provides modular, extensible functionality through:
- 44+ built-in actions
- 33+ built-in functions
- Easy custom plugin creation
- Hot-reload support (future)
- Health monitoring
use rust_rule_engine::RustRuleEngine;
let mut engine = RustRuleEngine::new();
engine.load_default_plugins()?;engine.load_plugin(StringUtilitiesPlugin::new())?;
engine.load_plugin(MathOperationsPlugin::new())?;Actions (13):
ToUpper(field)- Convert to uppercaseToLower(field)- Convert to lowercaseTrim(field)- Remove whitespaceTrimLeft(field)- Remove leading whitespaceTrimRight(field)- Remove trailing whitespaceReplace(field, old, new)- Replace substringReplaceAll(field, old, new)- Replace all occurrencesSubstring(field, start, length)- Extract substringConcat(field, ...values)- Concatenate stringsSplit(field, delimiter, output)- Split string into arrayPadLeft(field, length, char)- Pad leftPadRight(field, length, char)- Pad rightReverse(field)- Reverse string
Functions (7):
Length(string)- String lengthContains(string, substring)- Check substringStartsWith(string, prefix)- Check prefixEndsWith(string, suffix)- Check suffixIndexOf(string, substring)- Find positionIsEmpty(string)- Check if emptyCharAt(string, index)- Get character at position
Example:
rule "NormalizeEmail" {
when user.email != ""
then
ToLower(user.email);
Trim(user.email);
}
Actions (12):
Increment(field, amount)- Add to fieldDecrement(field, amount)- Subtract from fieldMultiply(field, factor)- Multiply fieldDivide(field, divisor)- Divide fieldMod(field, divisor)- Modulo operationAbs(field)- Absolute valueRound(field, decimals)- Round numberCeil(field)- Round upFloor(field)- Round downClamp(field, min, max)- Constrain valuePow(field, exponent)- PowerSqrt(field)- Square root
Functions (8):
Max(a, b)- Maximum valueMin(a, b)- Minimum valueAvg(...values)- AverageSum(...values)- Sum of valuesRandom()- Random 0-1RandomInt(min, max)- Random integerIsEven(number)- Check if evenIsOdd(number)- Check if odd
Example:
rule "ApplyDiscount" {
when order.amount > 1000
then
Multiply(order.amount, 0.9); // 10% discount
Round(order.amount, 2); // 2 decimals
}
Actions (8):
SetNow(field)- Set current timestampAddDays(field, days)- Add daysAddHours(field, hours)- Add hoursAddMinutes(field, minutes)- Add minutesFormatDate(field, format)- Format dateParseDate(field, format)- Parse date stringSetDate(field, year, month, day)- Set specific dateTruncate(field, unit)- Truncate to unit
Functions (6):
Now()- Current timestampDayOfWeek(date)- Get day of week (1-7)DayOfMonth(date)- Get day of monthMonth(date)- Get monthYear(date)- Get yearIsWeekend(date)- Check if weekend
Example:
rule "SetExpiration" {
when order.created_at != ""
then
SetNow(order.expires_at);
AddDays(order.expires_at, 30);
}
Actions (6):
ValidateEmail(field, error_field)- Email validationValidateURL(field, error_field)- URL validationValidateNumeric(field, error_field)- Number validationValidateAlpha(field, error_field)- Alphabetic validationValidateRange(field, min, max, error_field)- Range checkValidatePattern(field, pattern, error_field)- Regex match
Functions (6):
IsEmail(string)- Check if valid emailIsURL(string)- Check if valid URLIsNumeric(string)- Check if numericIsAlpha(string)- Check if alphabeticInRange(value, min, max)- Check rangeMatchesPattern(string, pattern)- Regex match
Example:
rule "ValidateUser" {
when user.email != ""
then
ValidateEmail(user.email, user.errors);
ValidateRange(user.age, 18, 120, user.errors);
}
Actions (7):
Append(array, value)- Add to arrayRemove(array, index)- Remove from arraySort(array)- Sort arrayReverse(array)- Reverse arrayFilter(array, condition, output)- Filter arrayMap(array, operation, output)- Transform arrayClear(array)- Empty array
Functions (6):
Length(array)- Array lengthContains(array, value)- Check membershipIndexOf(array, value)- Find indexFirst(array)- Get first elementLast(array)- Get last elementIsEmpty(array)- Check if empty
Example:
rule "ProcessItems" {
when order.items != []
then
Sort(order.items);
Log("Processing " + Length(order.items) + " items");
}
use rust_rule_engine::RulePlugin;
pub struct MyCustomPlugin {
name: String,
}
impl MyCustomPlugin {
pub fn new() -> Self {
Self {
name: "MyCustomPlugin".to_string(),
}
}
}
impl RulePlugin for MyCustomPlugin {
fn name(&self) -> &str {
&self.name
}
fn version(&self) -> &str {
"1.0.0"
}
fn description(&self) -> &str {
"My custom plugin description"
}
fn register_actions(&self, engine: &mut RustRuleEngine) -> Result<()> {
// Register your custom actions
engine.register_action("MyAction", |facts, params| {
// Action implementation
Ok(())
});
Ok(())
}
fn register_functions(&self, engine: &mut RustRuleEngine) -> Result<()> {
// Register your custom functions
engine.register_function("MyFunction", |facts, params| {
// Function implementation
Ok(Value::String("result".to_string()))
});
Ok(())
}
fn on_load(&mut self) -> Result<()> {
println!("Plugin loaded!");
Ok(())
}
fn on_unload(&mut self) -> Result<()> {
println!("Plugin unloaded!");
Ok(())
}
fn health_check(&self) -> Result<()> {
// Health check logic
Ok(())
}
}let mut engine = RustRuleEngine::new();
engine.load_plugin(MyCustomPlugin::new())?;rule "UseCustom" {
when condition
then MyAction(field, param);
}
Create → Load → Register → Active → Health Check → Unload
↓ ↓ ↓ ↓ ↓ ↓
new() on_load() register_*() (usage) health_check() on_unload()
// Check plugin health
let health = engine.plugin_health("StringUtilities")?;
match health {
PluginHealth::Healthy => println!("✅ Plugin healthy"),
PluginHealth::Warning(msg) => println!("⚠️ Warning: {}", msg),
PluginHealth::Error(msg) => println!("❌ Error: {}", msg),
}
// Get all plugin stats
let stats = engine.plugin_stats();
for stat in stats {
println!("{}: {} actions, {} functions",
stat.name, stat.action_count, stat.function_count);
}// ✅ Good: Single responsibility
StringUtilitiesPlugin
MathOperationsPlugin
// ❌ Bad: Too broad
EverythingPluginimpl RulePlugin for MyPlugin {
fn register_actions(&self, engine: &mut RustRuleEngine) -> Result<()> {
engine.register_action("MyAction", |facts, params| {
// ✅ Proper error handling
let value = params.get(0)
.ok_or_else(|| "Missing parameter")?;
Ok(())
});
Ok(())
}
}impl RulePlugin for MyPlugin {
fn description(&self) -> &str {
"MyPlugin provides:
- MyAction(field, param): Description
- MyFunction(value): Description"
}
}fn version(&self) -> &str {
"1.0.0" // Semantic versioning
}See examples/ directory for:
- Custom plugin implementations
- Advanced plugin patterns
- Integration examples
See Also:
- FEATURES.md - Core features
- API_REFERENCE.md - API documentation
Last Updated: 2025-10-31 (v0.10.0)