swayipc_types/utils/
node.rs1use crate::reply::Node;
2
3impl Node {
4 pub fn find_as_ref<F>(&self, predicate: F) -> Option<&Node>
5 where
6 F: Copy + Fn(&Node) -> bool,
7 {
8 if predicate(self) {
9 return Some(self);
10 }
11 for node in &self.nodes {
12 let node = node.find_as_ref(predicate);
13 if node.is_some() {
14 return node;
15 }
16 }
17 for node in &self.floating_nodes {
18 let node = node.find_as_ref(predicate);
19 if node.is_some() {
20 return node;
21 }
22 }
23 None
24 }
25
26 pub fn find<F>(self, predicate: F) -> Option<Node>
27 where
28 F: Copy + Fn(&Node) -> bool,
29 {
30 if predicate(&self) {
31 return Some(self);
32 }
33 let Node {
34 nodes,
35 floating_nodes,
36 ..
37 } = self;
38 for node in nodes {
39 let node = node.find(predicate);
40 if node.is_some() {
41 return node;
42 }
43 }
44 for node in floating_nodes {
45 let node = node.find(predicate);
46 if node.is_some() {
47 return node;
48 }
49 }
50 None
51 }
52
53 pub fn find_focused_as_ref<F>(&self, predicate: F) -> Option<&Node>
54 where
55 F: Copy + Fn(&Node) -> bool,
56 {
57 if predicate(self) {
58 return Some(self);
59 }
60 if self.focus.is_empty() {
61 return None;
62 }
63 let first = self.focus[0];
64 for node in &self.nodes {
65 if node.id == first {
66 return node.find_focused_as_ref(predicate);
67 }
68 }
69 for node in &self.floating_nodes {
70 if node.id == first {
71 return node.find_focused_as_ref(predicate);
72 }
73 }
74 None
75 }
76
77 pub fn find_focused<F>(self, predicate: F) -> Option<Node>
78 where
79 F: Copy + Fn(&Node) -> bool,
80 {
81 if predicate(&self) {
82 return Some(self);
83 }
84 let Node {
85 nodes,
86 floating_nodes,
87 focus,
88 ..
89 } = self;
90 if focus.is_empty() {
91 return None;
92 }
93 let first = focus[0];
94 for node in nodes {
95 if node.id == first {
96 return node.find_focused(predicate);
97 }
98 }
99 for node in floating_nodes {
100 if node.id == first {
101 return node.find_focused(predicate);
102 }
103 }
104 None
105 }
106
107 pub fn iter(&self) -> NodeIterator<'_> {
108 NodeIterator { queue: vec![self] }
109 }
110}
111
112pub struct NodeIterator<'a> {
113 queue: Vec<&'a Node>,
114}
115
116impl<'a> Iterator for NodeIterator<'a> {
117 type Item = &'a Node;
118
119 fn next(&mut self) -> Option<&'a Node> {
120 match self.queue.pop() {
121 None => None,
122 Some(result) => {
123 self.queue
124 .extend(result.nodes.iter().chain(result.floating_nodes.iter()));
125 Some(result)
126 }
127 }
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use crate::NodeBorder;
135 use crate::NodeLayout;
136 use crate::NodeType;
137 use crate::Orientation;
138 use crate::Rect;
139
140 fn rect() -> Rect {
141 Rect {
142 x: 0,
143 y: 0,
144 width: 10,
145 height: 10,
146 }
147 }
148
149 fn mk_node(name: Option<String>, node_type: NodeType, nodes: Vec<Node>) -> Node {
150 Node {
151 id: 1,
152 name,
153 node_type,
154 border: NodeBorder::Normal,
155 current_border_width: 0,
156 layout: NodeLayout::Tabbed,
157 percent: None,
158 rect: rect(),
159 window_rect: rect(),
160 deco_rect: rect(),
161 geometry: rect(),
162 urgent: false,
163 focused: false,
164 focus: Vec::new(),
165 nodes,
166 floating_nodes: Vec::new(),
167 sticky: false,
168 representation: None,
169 fullscreen_mode: None,
170 floating: None,
171 scratchpad_state: None,
172 app_id: None,
173 pid: None,
174 window: None,
175 num: None,
176 window_properties: None,
177 marks: Vec::new(),
178 inhibit_idle: None,
179 idle_inhibitors: None,
180 shell: None,
181 visible: None,
182 output: None,
183 sandbox_engine: None,
184 sandbox_app_id: None,
185 sandbox_instance_id: None,
186 tag: None,
187 foreign_toplevel_identifier: None,
188 orientation: Orientation::None,
189 }
190 }
191
192 #[test]
193 fn returns_the_given_root_node_first() {
194 let root = mk_node(Some(String::from("root")), NodeType::Root, vec![]);
195 let mut iterator = root.iter();
196 assert_eq!(iterator.next().unwrap().name, Some("root".to_string()));
197 }
198
199 #[test]
200 fn returns_children_of_the_given_node() {
201 let root = mk_node(
202 Some("root".to_string()),
203 NodeType::Root,
204 vec![mk_node(Some("child".to_string()), NodeType::Con, vec![])],
205 );
206 let mut iterator = root.iter();
207 iterator.next();
208 assert_eq!(iterator.next().unwrap().name, Some("child".to_string()));
209 }
210
211 #[test]
212 fn returns_transitive_children_of_the_given_node() {
213 let root = mk_node(
214 Some("root".to_string()),
215 NodeType::Root,
216 vec![mk_node(
217 Some("child".to_string()),
218 NodeType::Con,
219 vec![mk_node(
220 Some("grandchild".to_string()),
221 NodeType::Con,
222 vec![],
223 )],
224 )],
225 );
226 let mut iterator = root.iter();
227 iterator.next();
228 iterator.next();
229 assert_eq!(
230 iterator.next().unwrap().name,
231 Some("grandchild".to_string())
232 );
233 }
234
235 #[test]
236 fn returns_none_at_the_end() {
237 let root = mk_node(Some("root".to_string()), NodeType::Root, vec![]);
238 let mut iterator = root.iter();
239 iterator.next();
240 assert_eq!(iterator.next(), None);
241 }
242}