2 个版本
0.1.1 | 2023 年 10 月 9 日 |
---|---|
0.1.0 | 2023 年 10 月 9 日 |
#422 在 并发
用于 3 crates
29KB
601 行
Rush
Rush 是一个通用的规则引擎。
Rush 提供了一般的计算抽象。可以有多个实现,并且可以任意组合。
条件并行计算
快速开始
const SIMPLE_RULE: &'static str = "
rule COMPLEX_RULE
when
age > 18
then
stage = 'adult'
";
fn main(){
let rh = Rush::from(Into::<ExprEngine>::into([SIMPLE_RULE]));
let res:HashMap<String,String> = rh.flow(r#"{"age":19}"#.parse::<Value>().unwrap()).unwrap();
assert_eq!(res.get("stage").unwrap().as_str(),"adult");
}
在这里,正则表达式直接生成。您实际上可以自己实现一些以与您的服务集成。
关键词
直接解析规则如下
The keyword cannot be repeated: when,then
rule [name] [description] [engine/default:expr] [...]
when
[condition 1];
[condition 2];
...
[condition n];
then
[key1 = execute 1];
[key2 = execute 2];
...
[keyn = execute n];
运算符
- 修饰符:+ - / * & | ^ % >> <<
- 比较运算符:> >= < <= == !=
- 逻辑运算符:|| &&
- 数字常量,如 i64,如果有 '.' 则为 f64
- 字符串常量(单引号:'foobar')
- 布尔常量:true false
- 括号以控制求值顺序( )
- 数组 [括号内用逗号分隔的任何内容:[1, 2, 'foo']]
- 包含函数示例:
contain([1,2.3,'hello'],1)
- 子函数:找到两个数组是否有子集
- 包含函数示例:
- 前缀:! - ~
- 空合并:null
- 函数:function_name(args)result
- 输入字段通过数字、字母和下划线,如果字段未找到则条件失败
函数
您可以像普通的 Rust 函数一样添加函数
let rh = rh
.register_function("abs", |i: i64| Ok(i.abs()));
Lua
const LUA_RULE_SCRIPT: &'static str = r#"
rule LUA_RULE_SCRIPT _ lua
lua_script:
function handle(req)
local resp = {}
if req.source == ONLINE_CHANNEL then
resp.message = "线上渠道"
elseif req.source == OFFLINE_CHANNEL then
resp.message = "线下渠道"
else
resp.message = "未知渠道:"..req.source
end
return resp
end
return {handle_function="handle"}
"#;
WASM
使用以下代码编译 WASM 文件,使用命令 cargo build --target wasm32-unknown-unknown --release
extern "C" {
fn success(ptr: *const u8, len: usize) -> u32;
}
#[no_mangle]
pub extern "C" fn handle(ptr: *mut c_char, len: u32) -> u32 {
unsafe {
let slice = std::slice::from_raw_parts(ptr, len as usize);
let cs = CStr::from_ptr(slice.as_ptr());
let cs = CString::from(cs);
let s = cs.to_str().unwrap();
let s = format!(r#"{{"input":{}}}"#, s);
success(s.as_ptr(), s.len());
}
1u32
}
在规则中引用此文件并调用:
const WASM_RULE: &'static str = "
rule WASM_RULE _ wasm
wasm_file: wasm_example/wasm_example_one.wasm
";
#[tokio::test]
async fn test_wasm_build() {
let rt = WasmRuntimeFactory::new().async_build(WASM_RULE).await.unwrap();
let result: HashMap<String, String> =
rt.async_flow(Value::String("hello".into())).await.unwrap();
assert_eq!(result.get("input").unwrap().as_str(), "hello");
}
抽象和结构
基准测试
如果您对库的运行开销有所担忧,这个仓库中已经内置了一系列的基准测试。您可以通过以下命令运行它们:cargo bench -- --verbose
库的设计注重快速,但尚未进行积极的性能分析和优化。然而,对于大多数应用来说,它已经足够好了。
以下是我在MacBook Pro(CPU 2.6 GHz Intel Core i7)上的测试结果,[最低值,平均值,最高值]
assign_simple_parse time: [620.70 ns 625.08 ns 630.18 ns]
rule_full_parse time: [7.5513 µs 7.5794 µs 7.6094 µs]
multi_flow time: [15.363 µs 15.721 µs 16.184 µs]
sync_flow time: [2.9953 µs 3.0295 µs 3.0700 µs]
single_parse time: [165.08 ns 174.83 ns 186.49 ns]
simple_parse time: [2.6358 µs 2.6470 µs 2.6591 µs]
full_parse time: [19.868 µs 20.089 µs 20.356 µs]
have_function_rush time: [6.9074 µs 6.9507 µs 7.0011 µs]
lua_async_flow time: [10.731 µs 10.847 µs 10.970 µs]
wasm_async_flow time: [8.7260 µs 8.8046 µs 8.8806 µs]
计划
目前支持将表达式作为计数单元格。未来还计划支持Lua和WASM。
许可证
本项目采用MIT通用许可证。您可以在不咨询作者的情况下自由地集成、分叉和修改此代码,只要在您的作品中适当引用作者。
依赖
~3–10MB
~95K SLoC