forester_rs/runtime/rtree/
macros.rs

1/// Creates a list of arguments.
2///
3/// #Example
4///
5/// ```
6///
7/// use std::collections::HashMap;
8/// use forester_rs::*;
9/// use forester_rs::runtime::args::{RtArgs, RtArgument, RtValue};
10/// use forester_rs::runtime::args::RtValueNumber;
11/// #[test]
12/// fn test(){
13///      assert_eq!(
14///             args!(arg!("a" , rt_str!("a")), arg!("b" , rt_num!(i 1))),
15///             RtArgs(vec![
16///                 RtArgument::new("a".to_string(), RtValue::str("a".to_string())),
17///                 RtArgument::new("b".to_string(), RtValue::int(1)),
18///             ])
19///         )
20/// }
21/// ```
22#[macro_export]
23macro_rules! args {
24    [] => {{
25       RtArgs(vec![])
26    }};
27    () => {{
28       RtArgs(vec![])
29    }};
30    [$($rt_elems:expr),+  ] => {{
31        let mut elems = Vec::new();
32        $( elems.push($rt_elems) ; )+
33        RtArgs(elems)
34    }};
35    ($($rt_elems:expr),+ ) => {{
36        let mut elems = Vec::new();
37        $( elems.push($rt_elems) ; )+
38        RtArgs(elems)
39    }};
40
41}
42
43/// Creates an argument RtArgument.
44/// Accepts a string and a value
45///
46/// #Example
47///
48/// ```
49///
50/// use std::collections::HashMap;
51/// use forester_rs::*;
52/// use forester_rs::runtime::args::{RtArgument, RtValue};
53/// use forester_rs::runtime::args::RtValueNumber;
54/// #[test]
55/// fn test(){
56///      let x = arg!("a" , rt_array![rt_num!(i 1), rt_str!("a")]);
57///         assert_eq!(
58///             x,
59///             RtArgument::new(
60///                 "a".to_string(),
61///                 RtValue::Array(vec![RtValue::int(1), RtValue::str("a".to_string())])
62///             )
63///         );
64/// }
65/// ```
66/// ```
67/// use std::collections::HashMap;
68/// use forester_rs::*;
69/// use forester_rs::runtime::args::{RtArgument, RtValue};
70/// use forester_rs::runtime::args::RtValueNumber;
71///
72///  fn test(){
73///         assert_eq!(
74///             arg!("a" , rt_obj!{
75///                 "l" => rt_array![rt_str!("a"),rt_str!("b")]
76///                 "r" => rt_num!(i 15)
77///             }),
78///             RtArgument::new(
79///                 "a".to_string(),
80///                 RtValue::Object(HashMap::from_iter(vec![
81///                     (
82///                         "l".to_string(),
83///                         RtValue::Array(vec![
84///                             RtValue::str("a".to_string()),
85///                             RtValue::str("b".to_string())
86///                         ])
87///                     ),
88///                     ("r".to_string(), RtValue::int(15)),
89///                 ]))
90///             )
91///         );
92/// }
93///
94/// ```
95#[macro_export]
96macro_rules! arg {
97    ($name:expr , $value:expr) => {{
98        RtArgument::new($name.to_string(), $value)
99    }};
100}
101
102/// RtValue::String that accepts &str as argument
103#[macro_export]
104macro_rules! rt_str {
105    ($value:expr) => {{
106        RtValue::str($value.to_string())
107    }};
108}
109
110/// RtValue::Pointer that accepts &str as argument
111#[macro_export]
112macro_rules! rt_ptr {
113    ($value:expr) => {{
114        RtValue::Pointer($value.to_string())
115    }};
116}
117
118/// RtValue::Bool that accepts true | false  as argument
119#[macro_export]
120macro_rules! rt_bool {
121    (true) => {{
122        RtValue::Bool(true)
123    }};
124    (false) => {{
125        RtValue::Bool(false)
126    }};
127}
128
129/// RtValue::Number that accepts (i i64) | (f f64) | (b usize) (h usize)  as argument
130#[macro_export]
131macro_rules! rt_num {
132    (i$value:expr) => {{
133        RtValue::Number(RtValueNumber::Int($value))
134    }};
135    (f$value:expr) => {{
136        RtValue::Number(RtValueNumber::Float($value))
137    }};
138    (b$value:expr) => {{
139        RtValue::Number(RtValueNumber::Binary($value))
140    }};
141    (h$value:expr) => {{
142        RtValue::Number(RtValueNumber::Hex($value))
143    }};
144}
145
146/// RtValue::Array that has the same behaviour as an array
147#[macro_export]
148macro_rules! rt_array {
149    [] => {{
150        RtValue::Array(Vec::new())
151    }};
152    () => {{
153        RtValue::Array(Vec::new())
154    }};
155    [$($rt_elems:expr),+  ] => {{
156        let mut elems = Vec::new();
157        $( elems.push($rt_elems) ; )+
158        RtValue::Array(elems)
159    }};
160    ($($rt_elems:expr),+ ) => {{
161        let mut elems = Vec::new();
162        $( elems.push($rt_elems) ; )+
163        RtValue::Array(elems)
164    }};
165
166}
167
168/// RtValue::Object that has the same behaviour as an json_object
169#[macro_export]
170macro_rules! rt_obj {
171    {} => {{
172        RtValue::Object(HashMap::new())
173    }};
174    () => {{
175       RtValue::Object(HashMap::new())
176    }};
177
178    {$($name:expr => $val:expr)+ } => {{
179        let mut elems = Vec::new();
180        $( elems.push(($name.to_string(),$val)) ; )+
181        RtValue::Object(HashMap::from_iter(elems))
182    }}
183}
184
185/// Creates RNodeName
186///
187/// # Example
188/// ```
189/// use std::collections::HashMap;
190/// use forester_rs::*;
191/// use forester_rs::runtime::args::{RtArgument, RtValue};
192/// use forester_rs::runtime::args::RtValueNumber;
193/// use forester_rs::runtime::rtree::rnode::{FlowType, RNodeName};
194///
195///  fn test(){
196///         assert_eq!(
197///           node_name!(),
198///           RNodeName::Lambda  
199///         );
200///         assert_eq!(
201///           node_name!("name"),
202///           RNodeName::Name("name".to_string(),"".to_string())
203///         );
204///         assert_eq!(
205///           node_name!("name", "alias"),
206///           RNodeName::Alias("name".to_string(),"alias".to_string(),"".to_string())
207///         );
208///         assert_eq!(
209///           node_name!("name", "alias", "path"),
210///           RNodeName::Alias("name".to_string(),"alias".to_string(),"path".to_string())
211///         );
212///
213/// }
214///
215/// ```
216#[macro_export]
217macro_rules! node_name {
218    () => {{
219        RNodeName::Lambda
220    }};
221    ($name:expr) => {{
222        RNodeName::Name($name.to_string(),"".to_string())
223    }};
224    ($name:expr, $alias:expr) => {{
225        RNodeName::Alias($name.to_string(), $alias.to_string(),"".to_string())
226    }};
227    ($name:expr, $alias:expr, $path:expr) => {{
228        RNodeName::Alias($name.to_string(), $alias.to_string(),$path.to_string())
229    }};
230}
231
232/// Creates RtNodeBuilder::Leaf(..)
233///
234/// # Example
235/// ```
236/// use forester_rs::runtime::args::RtArgs;
237/// use std::collections::HashMap;
238/// use forester_rs::*;
239/// use forester_rs::runtime::args::{RtArgument, RtValue};
240/// use forester_rs::runtime::args::RtValueNumber;
241/// use forester_rs::runtime::rtree::builder::RtNodeBuilder;
242/// use forester_rs::runtime::rtree::rnode::RNodeName;
243///
244///  fn test(){
245///         let action = action!();
246///         let action = action!(node_name!("name"));
247///         let action = action!(node_name!("name"), args!());
248///         
249/// }
250///
251/// ```
252#[macro_export]
253macro_rules! action {
254    () => {{
255        RtNodeBuilder::leaf(node_name!(), args!())
256    }};
257    ($name:expr) => {{
258        RtNodeBuilder::leaf($name, args!())
259    }};
260
261    ($name:expr,$args:expr) => {{
262        RtNodeBuilder::leaf($name, $args)
263    }};
264}
265
266/// Creates RtNodeBuilder::flow(..)
267/// The syntax is the following:
268///  with enlisting
269/// `flow!(type name, args; children...)`
270///  
271///  with given vec
272///  `flow!(type name, args, children_vec)`
273/// # Example
274/// ```
275/// use forester_rs::runtime::args::RtArgs;
276/// use std::collections::HashMap;
277/// use forester_rs::*;
278/// use forester_rs::runtime::args::{RtArgument, RtValue};
279/// use forester_rs::runtime::args::RtValueNumber;
280/// use forester_rs::runtime::rtree::builder::RtNodeBuilder;
281/// use forester_rs::runtime::rtree::rnode::{FlowType, RNodeName};
282///
283///  fn test(){
284///         
285///         let flow_with_enlist = flow!(fallback node_name!(), args!();
286///                         action!(),
287///                         action!(),
288///                         action!(),
289///                         action!()
290///                     );
291///
292///         let actions = vec![ action!(), action!(), action!() ];
293///         let flow_with_vec = flow!(fallback node_name!(), args!(), actions);
294///
295/// }
296///
297/// ```
298#[macro_export]
299macro_rules! flow {
300    (root $name:expr, $args:expr; $($children:expr),+ ) => {{
301        let mut elems = Vec::new();
302        $( elems.push($children.into()) ; )+
303
304        RtNodeBuilder::flow(FlowType::Root, $name, $args, elems)
305    }};
306    (root $name:expr, $args:expr, $children:expr ) => {{
307        let elems = $children.into_iter().map(|v|v.into()).collect();
308        RtNodeBuilder::flow(FlowType::Root, $name, $args, elems)
309    }};
310    (parallel $name:expr, $args:expr; $($children:expr),+ ) => {{
311        let mut elems = Vec::new();
312        $( elems.push($children.into()) ; )+
313
314        RtNodeBuilder::flow(FlowType::Parallel, $name, $args, elems)
315    }};
316    (parallel $name:expr, $args:expr, $children:expr) => {{
317       let elems = $children.into_iter().map(|v|v.into()).collect();
318        $( elems.push($children.into()) ; )+
319
320        RtNodeBuilder::flow(FlowType::Parallel, $name, $args, elems)
321    }};
322
323    (sequence $name:expr, $args:expr; $($children:expr),+ ) => {{
324        let mut elems = Vec::new();
325        $( elems.push($children.into()) ; )+
326
327        RtNodeBuilder::flow(FlowType::Sequence, $name, $args, elems)
328    }};
329    (sequence $name:expr, $args:expr, $children:expr) => {{
330        let elems = $children.into_iter().map(|v|v.into()).collect();
331
332        RtNodeBuilder::flow(FlowType::Sequence, $name, $args, elems)
333    }};
334    (m_sequence $name:expr, $args:expr; $($children:expr),+ ) => {{
335        let mut elems = Vec::new();
336        $( elems.push($children.into()) ; )+
337
338        RtNodeBuilder::flow(FlowType::MSequence, $name, $args, elems)
339    }};
340    (m_sequence $name:expr, $args:expr, $children:expr) => {{
341        let elems = $children.into_iter().map(|v|v.into()).collect();
342
343        RtNodeBuilder::flow(FlowType::MSequence, $name, $args, elems)
344    }};
345    (r_sequence $name:expr, $args:expr; $($children:expr),+ ) => {{
346        let mut elems = Vec::new();
347        $( elems.push($children.into()) ; )+
348
349        RtNodeBuilder::flow(FlowType::RSequence, $name, $args, elems)
350    }};
351    (r_sequence $name:expr, $args:expr, $children:expr) => {{
352        let elems = $children.into_iter().map(|v|v.into()).collect();
353
354        RtNodeBuilder::flow(FlowType::RSequence, $name, $args, elems)
355    }};
356    (fallback $name:expr, $args:expr; $($children:expr),+ ) => {{
357        let mut elems = Vec::new();
358        $( elems.push($children.into()) ; )+
359
360        RtNodeBuilder::flow(FlowType::Fallback, $name, $args, elems)
361    }};
362    (fallback $name:expr, $args:expr, $children:expr) => {{
363        let elems = $children.into_iter().map(|v|v.into()).collect();
364
365        RtNodeBuilder::flow(FlowType::Fallback, $name, $args, elems)
366    }};
367    (r_fallback $name:expr, $args:expr; $($children:expr),+ ) => {{
368        let mut elems = Vec::new();
369        $( elems.push($children.into()) ; )+
370
371        RtNodeBuilder::flow(FlowType::RFallback, $name, $args, elems)
372    }};
373    (r_fallback $name:expr, $args:expr, $children:expr) => {{
374        let elems = $children.into_iter().map(|v|v.into()).collect();
375
376        RtNodeBuilder::flow(FlowType::RFallback, $name, $args, elems)
377    }};
378}
379
380/// Creates RtNodeBuilder::decorator(..)
381///
382/// # Example
383/// ```
384/// use forester_rs::runtime::args::RtArgs;
385/// use std::collections::HashMap;
386/// use forester_rs::*;
387/// use forester_rs::runtime::args::{RtArgument, RtValue};
388/// use forester_rs::runtime::args::RtValueNumber;
389/// use forester_rs::runtime::rtree::builder::RtNodeBuilder;
390/// use forester_rs::runtime::rtree::rnode::{FlowType,DecoratorType, RNodeName};
391///
392///  fn test(){
393///         
394///         let decorator = decorator!(
395///                         inverter args!(),
396///                         flow!(fallback node_name!(), args!(); action!())
397///                      );
398/// }
399///
400/// ```
401#[macro_export]
402macro_rules! decorator {
403    (inverter $args:expr, $child:expr ) => {{
404        RtNodeBuilder::decorator(DecoratorType::Inverter, $args, $child.into())
405    }};
406    (force_success $args:expr, $child:expr ) => {{
407        RtNodeBuilder::decorator(DecoratorType::ForceSuccess, $args, $child.into())
408    }};
409    (force_fail $args:expr, $child:expr ) => {{
410        RtNodeBuilder::decorator(DecoratorType::ForceFail, $args, $child.into())
411    }};
412    (repeat $args:expr, $child:expr ) => {{
413        RtNodeBuilder::decorator(DecoratorType::Repeat, $args, $child.into())
414    }};
415    (retry $args:expr, $child:expr ) => {{
416        RtNodeBuilder::decorator(DecoratorType::Retry, $args, $child.into())
417    }};
418    (timeout $args:expr, $child:expr ) => {{
419        RtNodeBuilder::decorator(DecoratorType::Timeout, $args, $child.into())
420    }};
421    (delay $args:expr, $child:expr ) => {{
422        RtNodeBuilder::decorator(DecoratorType::Delay, $args, $child.into())
423    }};
424}
425
426#[cfg(test)]
427mod tests {
428    use crate::runtime::args::{RtArgs, RtArgument, RtValue, RtValueNumber};
429    use std::collections::HashMap;
430
431    #[test]
432    fn arg() {
433        let x = arg!("a", rt_str!("v"));
434        assert_eq!(
435            x,
436            RtArgument::new("a".to_string(), RtValue::str("v".to_string()))
437        );
438
439        let x = arg!("a", rt_bool!(true));
440        assert_eq!(x, RtArgument::new("a".to_string(), RtValue::Bool(true)));
441
442        let x = arg!("a", rt_num!(i 10));
443        assert_eq!(x, RtArgument::new("a".to_string(), RtValue::int(10)));
444
445        let x = arg!("a", rt_array![]);
446        assert_eq!(x, RtArgument::new("a".to_string(), RtValue::Array(vec![])));
447
448        assert_eq!(
449            arg!(
450                "a",
451                rt_obj! {
452                "l" => rt_array![rt_str!("a"),rt_str!("b")]
453                "r" => rt_num!(i 15)
454                }
455            ),
456            RtArgument::new(
457                "a".to_string(),
458                RtValue::Object(HashMap::from_iter(vec![
459                    (
460                        "l".to_string(),
461                        RtValue::Array(vec![
462                            RtValue::str("a".to_string()),
463                            RtValue::str("b".to_string())
464                        ])
465                    ),
466                    ("r".to_string(), RtValue::int(15)),
467                ]))
468            )
469        );
470
471        assert_eq!(
472            args!(arg!("a", rt_str!("a")), arg!("b", rt_num!(i 1))),
473            RtArgs(vec![
474                RtArgument::new("a".to_string(), RtValue::str("a".to_string())),
475                RtArgument::new("b".to_string(), RtValue::int(1)),
476            ])
477        )
478    }
479}