2 个版本

0.1.1 2023 年 10 月 9 日
0.1.0 2023 年 10 月 9 日

#422并发


用于 3 crates

MIT 许可证

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

更多 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 示例

使用以下代码编译 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");
    }

抽象和结构

img.png

基准测试

如果您对库的运行开销有所担忧,这个仓库中已经内置了一系列的基准测试。您可以通过以下命令运行它们: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