forester_rs/runtime/rtree/
analyzer.rs1use crate::runtime::rtree::rnode::RNodeId;
2use crate::runtime::rtree::RNode;
3use crate::runtime::rtree::RuntimeTree;
4use std::collections::HashMap;
5
6pub struct RtTreeAnalyzer<'a> {
10 tree: &'a RuntimeTree,
11 parents: HashMap<RNodeId, RNodeId>,
12}
13
14impl<'a> RtTreeAnalyzer<'a> {
15 pub fn new(tree: &'a RuntimeTree) -> Self {
16 let mut parents = HashMap::new();
17 for (id, node) in tree.iter() {
18 for child in node.children() {
19 parents.insert(child, id);
20 }
21 }
22
23 Self { tree, parents }
24 }
25 pub fn parent(&self, id: &RNodeId) -> Option<&RNodeId> {
27 self.parents.get(id)
28 }
29
30 pub fn find_id_by<F>(&self, filter: F) -> Option<RNodeId>
32 where
33 F: Fn(&RNode) -> bool,
34 {
35 self.tree
36 .iter()
37 .find_map(|(id, node)| if filter(node) { Some(id) } else { None })
38 }
39 pub fn find_node_by<F>(&self, filter: F) -> Option<(RNodeId, &RNode)>
41 where
42 F: Fn(&RNode) -> bool,
43 {
44 self.tree
45 .iter()
46 .find(|(_id, node)| filter(node))
47 }
48 pub fn find_map_by<F, T>(&self, filter_map: F) -> Option<(RNodeId, T)>
50 where
51 F: Fn(&RNode) -> Option<T>,
52 {
53 self.tree
54 .iter()
55 .find_map(|(id, node)| filter_map(node).map(|v| (id, v)))
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use crate::runtime::args::RtArgs;
62 use crate::runtime::rtree::builder::RtNodeBuilder;
63 use crate::runtime::rtree::builder::RtTreeBuilder;
64 use crate::runtime::rtree::rnode::FlowType;
65 use crate::runtime::rtree::rnode::RNodeName;
66 use crate::*;
67
68 #[test]
69 fn find_and_parent() {
70 let mut rtb = RtTreeBuilder::new();
71
72 let flow = flow!(fallback node_name!("root"), args!();
73 flow!(sequence node_name!("seq"), args!();
74 action!(node_name!("action1"))
75 ),
76 action!(node_name!("action2"))
77 );
78
79 rtb.add_as_root(flow);
80 let tree = rtb.build().unwrap().0;
81
82 let analyzer = tree.analyze();
83 let a1 = analyzer.find_id_by(|n| n.is_name("action1")).unwrap();
84 let a2 = analyzer.find_id_by(|n| n.is_name("action2")).unwrap();
85 let root = analyzer.find_id_by(|n| n.is_name("root")).unwrap();
86 let seq = analyzer.find_id_by(|n| n.is_name("seq")).unwrap();
87
88 assert_eq!(analyzer.parent(&a1), Some(&seq));
89 assert_eq!(analyzer.parent(&a2), Some(&root));
90 assert_eq!(analyzer.parent(&root), None);
91 }
92}