1use std::cell::RefCell;
8use std::rc::{Rc, Weak};
9
10use super::{MatchType, MatchedNodes, NodeInner, NodeKind, NodeRef};
11use crate::error::{Error, Result};
12use crate::node::base::BaseNode;
13
14pub struct BranchNode;
16
17impl BranchNode {
18 pub fn set_partners(node: &NodeRef, partners: Option<Rc<RefCell<MatchedNodes>>>) {
23 let mut borrowed = node.borrow_mut();
24 match &mut borrowed.kind {
25 NodeKind::Branch {
26 partners: p_field, ..
27 } => {
28 *p_field = partners;
29 }
30 NodeKind::Base { .. } => panic!("set_partners() called on base node"),
31 }
32 }
33
34 pub fn partners(node: &NodeRef) -> Option<Rc<RefCell<MatchedNodes>>> {
39 let borrowed = node.borrow();
40 match &borrowed.kind {
41 NodeKind::Branch { partners, .. } => partners.clone(),
42 NodeKind::Base { .. } => panic!("partners() called on base node"),
43 }
44 }
45
46 pub fn set_base_match(
59 node: &NodeRef,
60 base: Weak<RefCell<NodeInner>>,
61 match_type: MatchType,
62 ) -> Result<()> {
63 if match_type.bits() < MatchType::CONTENT.bits()
64 || match_type.bits() > MatchType::FULL.bits()
65 {
66 return Err(Error::InvalidMatchType(match_type.bits()));
67 }
68 let mut borrowed = node.borrow_mut();
69 match &mut borrowed.kind {
70 NodeKind::Branch {
71 base_match,
72 match_type: mt,
73 ..
74 } => {
75 *base_match = base;
76 *mt = match_type;
77 Ok(())
78 }
79 NodeKind::Base { .. } => panic!("set_base_match() called on base node"),
80 }
81 }
82
83 pub fn set_match_type(node: &NodeRef, match_type: MatchType) -> Result<()> {
95 if match_type.bits() < MatchType::CONTENT.bits()
96 || match_type.bits() > MatchType::FULL.bits()
97 {
98 return Err(Error::InvalidMatchType(match_type.bits()));
99 }
100 let mut borrowed = node.borrow_mut();
101 match &mut borrowed.kind {
102 NodeKind::Branch { match_type: mt, .. } => {
103 *mt = match_type;
104 Ok(())
105 }
106 NodeKind::Base { .. } => panic!("set_match_type() called on base node"),
107 }
108 }
109
110 pub fn del_base_match(node: &NodeRef) {
115 let mut borrowed = node.borrow_mut();
116 match &mut borrowed.kind {
117 NodeKind::Branch {
118 base_match,
119 match_type,
120 ..
121 } => {
122 *base_match = Weak::new();
123 *match_type = MatchType::NONE;
124 }
125 NodeKind::Base { .. } => panic!("del_base_match() called on base node"),
126 }
127 }
128
129 pub fn base_match_type(node: &NodeRef) -> MatchType {
134 let borrowed = node.borrow();
135 match &borrowed.kind {
136 NodeKind::Branch { match_type, .. } => *match_type,
137 NodeKind::Base { .. } => panic!("base_match_type() called on base node"),
138 }
139 }
140
141 pub fn has_base_match(node: &NodeRef) -> bool {
146 let borrowed = node.borrow();
147 match &borrowed.kind {
148 NodeKind::Branch { base_match, .. } => base_match.upgrade().is_some(),
149 NodeKind::Base { .. } => panic!("has_base_match() called on base node"),
150 }
151 }
152
153 pub fn base_match(node: &NodeRef) -> Option<NodeRef> {
158 let borrowed = node.borrow();
159 match &borrowed.kind {
160 NodeKind::Branch { base_match, .. } => base_match.upgrade(),
161 NodeKind::Base { .. } => panic!("base_match() called on base node"),
162 }
163 }
164
165 pub fn is_left_tree(node: &NodeRef) -> bool {
173 {
175 let borrowed = node.borrow();
176 match &borrowed.kind {
177 NodeKind::Branch { is_left_tree, .. } => {
178 if let Some(is_left) = is_left_tree {
179 return *is_left;
180 }
181 }
182 NodeKind::Base { .. } => panic!("is_left_tree() called on base node"),
183 }
184 }
185
186 if let Some(base) = BranchNode::base_match(node) {
188 let left_matches = BaseNode::left(&base);
189 return left_matches.borrow().contains(node);
190 }
191
192 let parent = {
194 let borrowed = node.borrow();
195 borrowed.parent().upgrade()
196 };
197
198 if let Some(p) = parent {
199 BranchNode::is_left_tree(&p)
200 } else {
201 panic!("is_left_tree() called but no matched ancestor found")
202 }
203 }
204
205 pub fn set_is_left_tree(node: &NodeRef, is_left: bool) {
210 let mut borrowed = node.borrow_mut();
211 match &mut borrowed.kind {
212 NodeKind::Branch { is_left_tree, .. } => {
213 *is_left_tree = Some(is_left);
214 }
215 NodeKind::Base { .. } => panic!("set_is_left_tree() called on base node"),
216 }
217 }
218
219 pub fn is_match(node: &NodeRef, type_flags: MatchType) -> bool {
224 let match_type = BranchNode::base_match_type(node);
225 match_type.intersects(type_flags)
226 }
227
228 pub fn first_partner(node: &NodeRef, type_flags: MatchType) -> Option<NodeRef> {
237 let match_type = BranchNode::base_match_type(node);
238 if !match_type.intersects(type_flags) {
239 return None;
240 }
241
242 let partners = BranchNode::partners(node)?;
243 let partners_borrowed = partners.borrow();
244
245 for candidate in partners_borrowed.matches() {
246 let candidate_type = BranchNode::base_match_type(candidate);
247 if candidate_type.intersects(type_flags) {
248 return Some(Rc::clone(candidate));
249 }
250 }
251
252 None
253 }
254
255 pub fn child(node: &NodeRef, index: usize) -> NodeRef {
260 let borrowed = node.borrow();
261 let child = borrowed
262 .children()
263 .get(index)
264 .expect("child index out of bounds")
265 .clone();
266 assert!(child.borrow().is_branch(), "child is not a branch node");
267 child
268 }
269
270 pub fn parent(node: &NodeRef) -> Option<NodeRef> {
277 let borrowed = node.borrow();
278 borrowed.parent().upgrade().inspect(|p| {
279 assert!(p.borrow().is_branch(), "parent is not a branch node");
280 })
281 }
282
283 pub fn is_branch(node: &NodeRef) -> bool {
285 node.borrow().is_branch()
286 }
287}
288
289#[cfg(test)]
290mod tests {
291 use super::*;
292 use crate::node::{new_base_node, new_branch_node, NodeInner};
293 use std::rc::Rc;
294
295 #[test]
296 fn test_branch_base_match() {
297 let base = new_base_node(None);
298 let branch = new_branch_node(None);
299
300 assert!(!BranchNode::has_base_match(&branch));
301
302 BranchNode::set_base_match(&branch, Rc::downgrade(&base), MatchType::FULL).unwrap();
303
304 assert!(BranchNode::has_base_match(&branch));
305 assert_eq!(BranchNode::base_match_type(&branch), MatchType::FULL);
306
307 let retrieved_base = BranchNode::base_match(&branch).expect("should have base match");
308 assert_eq!(retrieved_base.borrow().id(), base.borrow().id());
309 }
310
311 #[test]
312 fn test_invalid_match_type() {
313 let base = new_base_node(None);
314 let branch = new_branch_node(None);
315
316 let result = BranchNode::set_base_match(&branch, Rc::downgrade(&base), MatchType::NONE);
317 assert!(result.is_err());
318 }
319
320 #[test]
321 fn test_del_base_match() {
322 let base = new_base_node(None);
323 let branch = new_branch_node(None);
324
325 BranchNode::set_base_match(&branch, Rc::downgrade(&base), MatchType::FULL).unwrap();
326 assert!(BranchNode::has_base_match(&branch));
327
328 BranchNode::del_base_match(&branch);
329 assert!(!BranchNode::has_base_match(&branch));
330 assert_eq!(BranchNode::base_match_type(&branch), MatchType::NONE);
331 }
332
333 #[test]
334 fn test_is_match() {
335 let branch = new_branch_node(None);
336 let base = new_base_node(None);
337
338 BranchNode::set_base_match(&branch, Rc::downgrade(&base), MatchType::CONTENT).unwrap();
340
341 assert!(BranchNode::is_match(&branch, MatchType::CONTENT));
346 assert!(!BranchNode::is_match(&branch, MatchType::CHILDREN));
347 assert!(BranchNode::is_match(&branch, MatchType::FULL)); BranchNode::set_match_type(&branch, MatchType::CHILDREN).unwrap();
351 assert!(!BranchNode::is_match(&branch, MatchType::CONTENT));
352 assert!(BranchNode::is_match(&branch, MatchType::CHILDREN));
353 assert!(BranchNode::is_match(&branch, MatchType::FULL)); BranchNode::set_match_type(&branch, MatchType::FULL).unwrap();
357 assert!(BranchNode::is_match(&branch, MatchType::CONTENT));
358 assert!(BranchNode::is_match(&branch, MatchType::CHILDREN));
359 assert!(BranchNode::is_match(&branch, MatchType::FULL));
360 }
361
362 #[test]
363 fn test_partners() {
364 let branch1 = new_branch_node(None);
365 let branch2 = new_branch_node(None);
366 let base = new_base_node(None);
367
368 assert!(BranchNode::partners(&branch1).is_none());
370
371 let partners = Rc::new(RefCell::new(MatchedNodes::new(Rc::downgrade(&base))));
373 partners.borrow_mut().add_match(branch2.clone());
374
375 BranchNode::set_partners(&branch1, Some(partners));
376
377 let retrieved_partners = BranchNode::partners(&branch1).expect("should have partners");
378 assert_eq!(retrieved_partners.borrow().match_count(), 1);
379 }
380
381 #[test]
382 fn test_branch_child_parent() {
383 let parent = new_branch_node(None);
384 let child = new_branch_node(None);
385
386 NodeInner::add_child_to_ref(&parent, child.clone());
387
388 let retrieved_child = BranchNode::child(&parent, 0);
389 assert_eq!(retrieved_child.borrow().id(), child.borrow().id());
390
391 let retrieved_parent = BranchNode::parent(&child).expect("should have parent");
392 assert_eq!(retrieved_parent.borrow().id(), parent.borrow().id());
393 }
394
395 #[test]
396 fn test_is_left_tree() {
397 let base = new_base_node(None);
398 let left_branch = new_branch_node(None);
399 let right_branch = new_branch_node(None);
400
401 BranchNode::set_base_match(&left_branch, Rc::downgrade(&base), MatchType::FULL).unwrap();
403 BranchNode::set_base_match(&right_branch, Rc::downgrade(&base), MatchType::FULL).unwrap();
404
405 BaseNode::left(&base)
407 .borrow_mut()
408 .add_match(left_branch.clone());
409 BaseNode::right(&base)
410 .borrow_mut()
411 .add_match(right_branch.clone());
412
413 assert!(BranchNode::is_left_tree(&left_branch));
414 assert!(!BranchNode::is_left_tree(&right_branch));
415 }
416
417 #[test]
418 fn test_first_partner() {
419 let base = new_base_node(None);
420 let branch1 = new_branch_node(None);
421 let branch2 = new_branch_node(None);
422 let branch3 = new_branch_node(None);
423
424 BranchNode::set_base_match(&branch1, Rc::downgrade(&base), MatchType::FULL).unwrap();
426
427 let partners = Rc::new(RefCell::new(MatchedNodes::new(Rc::downgrade(&base))));
429
430 BranchNode::set_base_match(&branch2, Rc::downgrade(&base), MatchType::CONTENT).unwrap();
431 BranchNode::set_base_match(&branch3, Rc::downgrade(&base), MatchType::CHILDREN).unwrap();
432
433 partners.borrow_mut().add_match(branch2.clone());
434 partners.borrow_mut().add_match(branch3.clone());
435
436 BranchNode::set_partners(&branch1, Some(partners));
437
438 let content_partner =
440 BranchNode::first_partner(&branch1, MatchType::CONTENT).expect("should find partner");
441 assert_eq!(content_partner.borrow().id(), branch2.borrow().id());
442
443 let children_partner =
445 BranchNode::first_partner(&branch1, MatchType::CHILDREN).expect("should find partner");
446 assert_eq!(children_partner.borrow().id(), branch3.borrow().id());
447 }
448}