1use std::cell::RefCell;
8use std::rc::Rc;
9
10use super::{MatchedNodes, NodeKind, NodeRef};
11
12pub struct BaseNode;
14
15impl BaseNode {
16 pub fn left(node: &NodeRef) -> Rc<RefCell<MatchedNodes>> {
21 let borrowed = node.borrow();
22 match &borrowed.kind {
23 NodeKind::Base { left, .. } => Rc::clone(left),
24 NodeKind::Branch { .. } => panic!("left() called on branch node"),
25 }
26 }
27
28 pub fn right(node: &NodeRef) -> Rc<RefCell<MatchedNodes>> {
33 let borrowed = node.borrow();
34 match &borrowed.kind {
35 NodeKind::Base { right, .. } => Rc::clone(right),
36 NodeKind::Branch { .. } => panic!("right() called on branch node"),
37 }
38 }
39
40 pub fn swap_left_right_matchings(node: &NodeRef) {
45 let mut borrowed = node.borrow_mut();
46 match &mut borrowed.kind {
47 NodeKind::Base { left, right } => {
48 std::mem::swap(left, right);
49 }
50 NodeKind::Branch { .. } => panic!("swap_left_right_matchings() called on branch node"),
51 }
52 }
53
54 pub fn child(node: &NodeRef, index: usize) -> NodeRef {
59 let borrowed = node.borrow();
60 let child = borrowed
61 .children()
62 .get(index)
63 .expect("child index out of bounds")
64 .clone();
65 assert!(child.borrow().is_base(), "child is not a base node");
66 child
67 }
68
69 pub fn parent(node: &NodeRef) -> Option<NodeRef> {
76 let borrowed = node.borrow();
77 borrowed.parent().upgrade().inspect(|p| {
78 assert!(p.borrow().is_base(), "parent is not a base node");
79 })
80 }
81
82 pub fn is_base(node: &NodeRef) -> bool {
84 node.borrow().is_base()
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use crate::node::{new_base_node, new_branch_node, NodeInner};
92
93 #[test]
94 fn test_base_left_right() {
95 let base = new_base_node(None);
96
97 let _left = BaseNode::left(&base);
99 let _right = BaseNode::right(&base);
100 }
101
102 #[test]
103 #[should_panic(expected = "left() called on branch node")]
104 fn test_left_on_branch_panics() {
105 let branch = new_branch_node(None);
106 let _left = BaseNode::left(&branch);
107 }
108
109 #[test]
110 fn test_swap_matchings() {
111 let base = new_base_node(None);
112 let branch = new_branch_node(None);
113
114 BaseNode::left(&base).borrow_mut().add_match(branch.clone());
116
117 assert_eq!(BaseNode::left(&base).borrow().match_count(), 1);
118 assert_eq!(BaseNode::right(&base).borrow().match_count(), 0);
119
120 BaseNode::swap_left_right_matchings(&base);
122
123 assert_eq!(BaseNode::left(&base).borrow().match_count(), 0);
124 assert_eq!(BaseNode::right(&base).borrow().match_count(), 1);
125 }
126
127 #[test]
128 fn test_base_child_parent() {
129 let parent = new_base_node(None);
130 let child = new_base_node(None);
131
132 NodeInner::add_child_to_ref(&parent, child.clone());
133
134 let retrieved_child = BaseNode::child(&parent, 0);
135 assert_eq!(retrieved_child.borrow().id(), child.borrow().id());
136
137 let retrieved_parent = BaseNode::parent(&child).expect("should have parent");
138 assert_eq!(retrieved_parent.borrow().id(), parent.borrow().id());
139 }
140}