rush_core/
rush.rs

1use crate::std_tool::{ArrayContain, ArraySub, Env};
2use crate::{
3    AsyncRuleFlow, CalcNode, Exec, Function, FunctionImpl, FunctionSet, HostFunction, RuleFlow,
4};
5use serde::{Deserialize, Serialize};
6use serde_json::{Map, Value};
7use std::collections::HashMap;
8use std::fmt::{Debug, Display, Formatter};
9use std::sync::Arc;
10use wd_tools::sync::Acl;
11
12pub struct Rush {
13    pub(crate) functions: Acl<HashMap<String, Arc<dyn Function>>>,
14    pub(crate) nodes: HashMap<String, Vec<Box<dyn CalcNode>>>,
15    pub(crate) nodes_seq: Vec<String>,
16    pub(crate) exec: HashMap<String, Box<dyn Exec>>,
17}
18
19impl Debug for Rush {
20    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
21        let mut fs = vec![];
22        for (i, _) in self.functions.share().iter() {
23            fs.push(i.to_string());
24        }
25        let mut nodes = vec![];
26        for (i, _) in self.nodes.iter() {
27            nodes.push(i.to_string());
28        }
29        let mut rules = vec![];
30        for (i, _) in self.exec.iter() {
31            rules.push(i.to_string());
32        }
33        write!(
34            f,
35            "{{ functions:{:?},nodes:{:?},rules:{:?} }}",
36            fs, nodes, rules
37        )
38    }
39}
40impl Display for Rush {
41    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42        Debug::fmt(self, f)
43    }
44}
45
46impl Rush {
47    pub fn new() -> Self {
48        let functions = Acl::new(HashMap::new());
49        let nodes = HashMap::new();
50        let nodes_seq = Vec::new();
51        let rules = HashMap::new();
52        let rh = Self {
53            functions,
54            nodes,
55            nodes_seq,
56            exec: rules,
57        };
58        rh.raw_register_function("contain", ArrayContain {})
59            .raw_register_function("sub", ArraySub {})
60            .raw_register_function("env", Env::default())
61    }
62    pub fn register_rule<
63        C: CalcNode + Send + Sync + 'static,
64        E: Exec + Send + Sync + 'static,
65        T: Into<String>,
66    >(
67        mut self,
68        name: T,
69        nodes: Vec<C>,
70        exec: E,
71    ) -> Self {
72        let name = name.into();
73        let mut ns: Vec<Box<dyn CalcNode>> = vec![];
74        for i in nodes {
75            ns.push(Box::new(i));
76        }
77        let mut index = usize::MAX;
78        if self.nodes.contains_key(&name) {
79            for (i,n) in self.nodes_seq.iter().enumerate(){
80                if n == &name{
81                    index = i;
82                    break
83                }
84            }
85        }
86        if index != usize::MAX{
87            self.nodes_seq.remove(index);
88        }
89        self.nodes_seq.push(name.clone());
90        self.nodes.insert(name.clone(), ns);
91        self.exec.insert(name, Box::new(exec));
92        self
93    }
94    pub fn delete_rule<T: AsRef<str>>(&mut self, name: T) {
95        let mut index = usize::MAX;
96        if self.exec.contains_key(name.as_ref()) {
97            for (i,n) in self.nodes_seq.iter().enumerate(){
98                if n == name.as_ref() {
99                    index = i;
100                    break
101                }
102            }
103        }
104        if index != usize::MAX{
105            self.nodes_seq.remove(index);
106        }
107        self.nodes.remove(name.as_ref());
108        self.exec.remove(name.as_ref());
109    }
110    pub fn raw_register_function<S: Into<String>, F: Function>(self, name: S, function: F) -> Self {
111        self.functions.update(|x| {
112            let mut map = (*x).clone();
113            map.insert(name.into(), Arc::new(function));
114            map
115        });
116        self
117    }
118    pub fn register_function<S: Into<String>, Args, Out, F>(self, name: S, function: F) -> Self
119    where
120        F: HostFunction<Args, Out> + 'static,
121        Out: Serialize,
122    {
123        self.raw_register_function(name, FunctionImpl::new(function))
124    }
125
126    pub fn delete_function<S: AsRef<str>>(self, name: S) -> Self {
127        self.functions.update(|x| {
128            let mut map = (*x).clone();
129            map.remove(name.as_ref());
130            map
131        });
132        self
133    }
134
135    pub fn execute(&self, obj: &Value, list: Vec<String>) -> anyhow::Result<Value> {
136        let mut output = Value::Object(Map::new());
137        for name in list.iter() {
138            if let Some(r) = self.exec.get(name) {
139                r.execute(self.functions.share(), obj, &mut output)?;
140            }
141        }
142        Ok(output)
143    }
144    /// input_value
145    /// 1. 计算匹配到的规则
146    /// 2. 找出规则进行结果生成
147    fn flow_value(&self, obj: Value) -> anyhow::Result<Value> {
148        let mut rules = vec![];
149        'lp: for k in self.nodes_seq.iter() {
150            let v = self.nodes.get(k).unwrap();
151            for i in v.iter() {
152                if !i.when(self.functions.share(), &obj)? {
153                    continue 'lp;
154                }
155            }
156            rules.push(k.to_string());
157        }
158        self.execute(&obj, rules)
159    }
160}
161
162impl<C, E, I: IntoIterator<Item = (String, Vec<C>, E)>> From<I> for Rush
163where
164    C: CalcNode + 'static,
165    E: Exec + 'static,
166{
167    fn from(value: I) -> Self {
168        let mut rush = Rush::new();
169        for (name, calc, exec) in value {
170            rush = rush.register_rule(name, calc, exec);
171        }
172        rush
173    }
174}
175
176impl FunctionSet for HashMap<String, Arc<dyn Function>> {
177    fn get(&self, name: &str) -> Option<Arc<dyn Function>> {
178        self.get(name).map(|a| a.clone())
179    }
180}
181
182impl RuleFlow for Rush {
183    fn flow<Obj: Serialize, Out: Deserialize<'static>>(&self, obj: Obj) -> anyhow::Result<Out> {
184        let value = serde_json::to_value(obj)?;
185        let result = self.flow_value(value)?;
186        let out = Out::deserialize(result)?;
187        Ok(out)
188    }
189}
190impl AsyncRuleFlow for Rush {}
191
192#[cfg(test)]
193mod test {
194    use crate::rush::Rush;
195    use crate::{CalcNode, Exec, FunctionSet, RuleFlow};
196    use serde::{Deserialize, Serialize};
197    use serde_json::Value;
198    use std::sync::Arc;
199
200    struct CalcNodeImpl;
201    impl CalcNode for CalcNodeImpl {
202        fn when(&self, _fs: Arc<dyn FunctionSet>, _input: &Value) -> anyhow::Result<bool> {
203            return Ok(true);
204        }
205    }
206    struct RuleImpl;
207    impl Exec for RuleImpl {
208        fn execute(
209            &self,
210            _fs: Arc<dyn FunctionSet>,
211            _input: &Value,
212            _output: &mut Value,
213        ) -> anyhow::Result<()> {
214            Ok(())
215        }
216    }
217    #[derive(Debug, Default, Serialize, Deserialize)]
218    struct ObjTest {
219        #[serde(default = "String::default")]
220        pub name: String,
221    }
222
223    //cargo test --color=always --lib rush::test::test_simple --no-fail-fast -- --exact unstable-options --show-output
224    #[test]
225    fn test_simple() {
226        let mr = Rush::new();
227        let result: ObjTest = mr
228            .flow(ObjTest {
229                name: "hello world".into(),
230            })
231            .expect("input failed");
232        println!("result ---> {result:?}");
233    }
234}