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 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 #[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}