moduforge_rules_engine/
lib.rs

1//! # moduforge-rules-engine
2//!
3//! moduforge-rules-engine 是一个对业务友好的开源业务规则引擎(BRE),用于根据 GoRules JSON 决策模型(JDM)标准执行决策模型。
4//!
5//! # 使用方法
6//!
7//! 要使用 Noop(默认)加载器执行简单决策,您可以使用以下代码:
8//!
9//! ```rust
10//! use serde_json::json;
11//! use moduforge_rules_engine::DecisionEngine;
12//! use moduforge_rules_engine::model::DecisionContent;
13//!
14//! async fn evaluate() {
15//!     let decision_content: DecisionContent = serde_json::from_str(include_str!("jdm_graph.json")).unwrap();
16//!     let engine = DecisionEngine::default();
17//!     let decision = engine.create_decision(decision_content.into());
18//!
19//!     let result = decision.evaluate(&json!({ "input": 12 })).await;
20//! }
21//! ```
22//!
23//! 另外,您也可以使用 `Decision::from` 函数间接创建决策,而无需构建引擎。
24//!
25//! # 加载器
26//!
27//! 对于更高级的用例,当您需要加载多个决策并使用图时,您可以使用以下预制的加载器之一:
28//! - FilesystemLoader - 使用给定路径作为根目录,尝试基于相对路径加载决策
29//! - MemoryLoader - 作为 HashMap(键值存储)工作
30//! - ClosureLoader - 允许定义简单的异步回调函数,该函数接收键作为参数并返回 `Arc<DecisionContent>` 实例
31//! - NoopLoader - (默认)无法加载决策,允许使用 create_decision(主要用于跨语言统一 API)
32//!
33//! ## 文件系统加载器
34//!
35//! 假设您有一个位于 /app/decisions 下的决策模型文件夹(.json 文件),您可以按以下方式使用 FilesystemLoader:
36//!
37//! ```rust
38//! use serde_json::json;
39//! use moduforge_rules_engine::DecisionEngine;
40//! use moduforge_rules_engine::loader::{FilesystemLoader, FilesystemLoaderOptions};
41//!
42//! async fn evaluate() {
43//!     let engine = DecisionEngine::new(FilesystemLoader::new(FilesystemLoaderOptions {
44//!         keep_in_memory: true, // 可选,保持在内存中以提高性能
45//!         root: "/app/decisions"
46//!     }));
47//!     
48//!     let context = json!({ "customer": { "joinedAt": "2022-01-01" } });
49//!     // 如果您计划多次使用它,可以缓存 JDM 以获得轻微的性能提升
50//!     // 在绑定(其他语言)的情况下,这种提升会更大
51//!     {
52//!         let promotion_decision = engine.get_decision("commercial/promotion.json").await.unwrap();
53//!         let result = promotion_decision.evaluate(&context).await.unwrap();
54//!     }
55//!     
56//!     // 或者按需加载
57//!     {
58//!         let result = engine.evaluate("commercial/promotion.json", &context).await.unwrap();
59//!     }
60//! }
61//!
62//!
63//! ```
64//!
65//! ## 自定义加载器
66//! 您可以通过实现 `DecisionLoader` trait 为 zen 引擎创建自定义加载器。
67//! 以下是 MemoryLoader 的实现示例:
68//! ```rust
69//! use std::collections::HashMap;
70//! use std::sync::{Arc, RwLock};
71//! use zen_engine::loader::{DecisionLoader, LoaderError, LoaderResponse};
72//! use zen_engine::model::DecisionContent;
73//!
74//! #[derive(Debug, Default)]
75//! pub struct MemoryLoader {
76//!     memory_refs: RwLock<HashMap<String, Arc<DecisionContent>>>,
77//! }
78//!
79//! impl MemoryLoader {
80//!     pub fn add<K, D>(&self, key: K, content: D)
81//!         where
82//!             K: Into<String>,
83//!             D: Into<DecisionContent>,
84//!     {
85//!         let mut mref = self.memory_refs.write().unwrap();
86//!         mref.insert(key.into(), Arc::new(content.into()));
87//!     }
88//!
89//!     pub fn get<K>(&self, key: K) -> Option<Arc<DecisionContent>>
90//!         where
91//!             K: AsRef<str>,
92//!     {
93//!         let mref = self.memory_refs.read().unwrap();
94//!         mref.get(key.as_ref()).map(|r| r.clone())
95//!     }
96//!
97//!     pub fn remove<K>(&self, key: K) -> bool
98//!         where
99//!             K: AsRef<str>,
100//!     {
101//!         let mut mref = self.memory_refs.write().unwrap();
102//!         mref.remove(key.as_ref()).is_some()
103//!     }
104//! }
105//!
106//! impl DecisionLoader for MemoryLoader {
107//! fn load<'a>(&'a self, key: &'a str) -> impl Future<Output = LoaderResponse> + 'a {
108//!     async move {
109//!         self.get(&key)
110//!             .ok_or_else(|| LoaderError::NotFound(key.to_string()).into())
111//!     }
112//! }
113//! ```
114
115#![deny(clippy::unwrap_used)]
116#![allow(clippy::module_inception)]
117
118pub mod config;
119pub mod decision;
120pub mod engine;
121pub mod error;
122pub mod handler;
123pub mod loader;
124#[path = "model/mod.rs"]
125pub mod model;
126pub mod util;
127
128pub use config::ZEN_CONFIG;
129pub use decision::Decision;
130pub use engine::{DecisionEngine, EvaluationOptions};
131pub use error::EvaluationError;
132pub use handler::graph::DecisionGraphResponse;
133pub use handler::graph::DecisionGraphTrace;
134pub use handler::graph::DecisionGraphValidationError;
135pub use handler::node::NodeError;
136pub use moduforge_rules_expression::Variable;