1use std::cell::{Cell, RefCell};
8use std::fmt::{self, Debug, Display, Formatter};
9use std::rc::{Rc, Weak};
10
11pub type NodeRef<T> = Rc<RefCell<TreeNode<T>>>;
13
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
22pub struct FormState {
23 pub checked: Option<bool>,
25}
26
27#[derive(Clone)]
29pub struct TreeNode<T> {
30 pub value: T,
31 parent: Option<Weak<RefCell<TreeNode<T>>>>,
32 children: Vec<NodeRef<T>>,
33 form_state: Cell<FormState>,
36 owner_document: Cell<Option<u64>>,
44}
45
46impl<T> TreeNode<T> {
47 pub fn new(value: T) -> NodeRef<T> {
49 Rc::new(RefCell::new(Self {
50 value,
51 parent: None,
52 children: Vec::new(),
53 form_state: Cell::new(FormState::default()),
54 owner_document: Cell::new(None),
55 }))
56 }
57
58 pub fn owner_document(&self) -> Option<u64> {
60 self.owner_document.get()
61 }
62
63 pub fn set_owner_document(&self, document_dom_id: u64) {
65 self.owner_document.set(Some(document_dom_id));
66 }
67
68 pub fn form_state(&self) -> FormState {
70 self.form_state.get()
71 }
72
73 pub fn set_form_state(&self, state: FormState) {
75 self.form_state.set(state);
76 }
77
78 pub fn checkedness(&self) -> Option<bool> {
80 self.form_state.get().checked
81 }
82
83 pub fn set_checkedness(&self, checked: bool) {
85 self.form_state.set(FormState {
86 checked: Some(checked),
87 });
88 }
89
90 pub fn parent(&self) -> Option<NodeRef<T>> {
92 self.parent.as_ref().and_then(|w| w.upgrade())
93 }
94
95 pub fn children(&self) -> &[NodeRef<T>] {
97 &self.children
98 }
99
100 pub fn clear_children(&mut self) {
102 for child in &self.children {
103 child.borrow_mut().parent = None;
104 }
105 self.children.clear();
106 }
107
108 pub fn add_child(parent: &NodeRef<T>, child: NodeRef<T>) {
110 child.borrow_mut().parent = Some(Rc::downgrade(parent));
111 parent.borrow_mut().children.push(child);
112 }
113
114 pub fn remove_child(parent: &NodeRef<T>, child: &NodeRef<T>) -> Option<NodeRef<T>> {
116 let position = {
117 let borrowed = parent.borrow();
118 borrowed
119 .children
120 .iter()
121 .position(|candidate| Rc::ptr_eq(candidate, child))
122 }?;
123 let removed = parent.borrow_mut().children.remove(position);
124 removed.borrow_mut().parent = None;
125 Some(removed)
126 }
127
128 pub fn detach(node: &NodeRef<T>) -> bool {
130 let Some(parent) = node.borrow().parent() else {
131 return false;
132 };
133 Self::remove_child(&parent, node).is_some()
134 }
135
136 pub fn append_child(parent: &NodeRef<T>, child: NodeRef<T>) -> bool {
140 if Self::is_inclusive_ancestor(&child, parent) {
141 return false;
142 }
143 Self::detach(&child);
144 Self::add_child(parent, child);
145 true
146 }
147
148 pub fn insert_before(parent: &NodeRef<T>, child: NodeRef<T>, reference: &NodeRef<T>) -> bool {
151 if Rc::ptr_eq(&child, reference) {
152 return reference
153 .borrow()
154 .parent()
155 .is_some_and(|candidate| Rc::ptr_eq(&candidate, parent));
156 }
157 if Self::is_inclusive_ancestor(&child, parent) {
158 return false;
159 }
160 if !reference
161 .borrow()
162 .parent()
163 .is_some_and(|candidate| Rc::ptr_eq(&candidate, parent))
164 {
165 return false;
166 }
167
168 Self::detach(&child);
169 let Some(index) = parent
170 .borrow()
171 .children
172 .iter()
173 .position(|candidate| Rc::ptr_eq(candidate, reference))
174 else {
175 return false;
176 };
177 Self::insert_child_at(parent, index, child);
178 true
179 }
180
181 pub fn is_inclusive_ancestor(ancestor: &NodeRef<T>, node: &NodeRef<T>) -> bool {
182 let mut current = Some(Rc::clone(node));
183 while let Some(candidate) = current {
184 if Rc::ptr_eq(ancestor, &candidate) {
185 return true;
186 }
187 current = candidate.borrow().parent();
188 }
189 false
190 }
191
192 pub fn insert_child_at(parent: &NodeRef<T>, index: usize, child: NodeRef<T>) {
194 child.borrow_mut().parent = Some(Rc::downgrade(parent));
195 parent.borrow_mut().children.insert(index, child);
196 }
197
198 pub fn add_child_value(parent: &NodeRef<T>, value: T) -> NodeRef<T> {
200 let child = Self::new(value);
201 Self::add_child(parent, Rc::clone(&child));
202 child
203 }
204
205 pub fn replace_child(
207 parent: &NodeRef<T>,
208 index: usize,
209 new_child: NodeRef<T>,
210 ) -> Option<NodeRef<T>> {
211 let mut p = parent.borrow_mut();
212 if index < p.children.len() {
213 let old_child = std::mem::replace(&mut p.children[index], new_child);
214 old_child.borrow_mut().parent = None;
215 Some(old_child)
216 } else {
217 None
218 }
219 }
220
221 pub fn find_children_by<F>(&self, predicate: F) -> Vec<NodeRef<T>>
223 where
224 F: Fn(&T) -> bool,
225 {
226 self.children
227 .iter()
228 .filter(|c| predicate(&c.borrow().value))
229 .cloned()
230 .collect()
231 }
232
233 pub fn clone_node(&self, deep: bool) -> NodeRef<T>
235 where
236 T: Clone,
237 {
238 let new_node = Rc::new(RefCell::new(TreeNode {
239 value: self.value.clone(),
240 children: Vec::new(),
241 parent: None,
242 form_state: Cell::new(self.form_state.get()),
245 owner_document: Cell::new(self.owner_document.get()),
248 }));
249
250 if deep {
251 for child in &self.children {
252 let child_clone = child.borrow().clone_node(true);
253 child_clone.borrow_mut().parent = Some(Rc::downgrade(&new_node));
254 new_node.borrow_mut().children.push(child_clone);
255 }
256 }
257
258 new_node
259 }
260}
261
262#[derive(Clone)]
264pub struct Tree<T> {
265 pub root: NodeRef<T>,
266 version: Cell<u64>,
272}
273
274impl<T: Clone> Tree<T> {
275 pub fn new(root_value: T) -> Self {
277 Self {
278 root: TreeNode::new(root_value),
279 version: Cell::new(0),
280 }
281 }
282
283 pub fn from_root(root: NodeRef<T>) -> Self {
288 Self {
289 root,
290 version: Cell::new(0),
291 }
292 }
293
294 pub fn mark_dirty(&self) {
296 self.version.set(self.version.get() + 1);
297 }
298
299 pub fn version(&self) -> u64 {
301 self.version.get()
302 }
303
304 pub fn traverse<F>(&self, mut f: F)
306 where
307 F: FnMut(&NodeRef<T>),
308 {
309 fn visit<T, F>(node: &NodeRef<T>, f: &mut F)
310 where
311 F: FnMut(&NodeRef<T>),
312 {
313 f(node);
314 for child in &node.borrow().children {
315 visit(child, f);
316 }
317 }
318 visit(&self.root, &mut f);
319 }
320
321 pub fn map<U, F>(&self, f: F) -> Tree<U>
323 where
324 F: Fn(&T) -> U,
325 U: Clone,
326 {
327 fn map_node<T, U, F>(node: &NodeRef<T>, f: &F) -> NodeRef<U>
328 where
329 F: Fn(&T) -> U,
330 U: Clone,
331 {
332 let n = node.borrow();
333 let new_node = TreeNode::new(f(&n.value));
334 for child in &n.children {
335 let mapped_child = map_node(child, f);
336 TreeNode::add_child(&new_node, mapped_child);
337 }
338 new_node
339 }
340
341 Tree {
342 root: map_node(&self.root, &f),
343 version: Cell::new(0),
344 }
345 }
346
347 pub fn map_with_node<U, F>(&self, f: F) -> Tree<U>
349 where
350 F: Fn(&NodeRef<T>) -> U,
351 U: Clone,
352 {
353 fn map_node<T, U, F>(node: &NodeRef<T>, f: &F) -> NodeRef<U>
354 where
355 F: Fn(&NodeRef<T>) -> U,
356 U: Clone,
357 {
358 let new_node = TreeNode::new(f(node));
359 for child in &node.borrow().children {
360 let mapped_child = map_node(child, f);
361 TreeNode::add_child(&new_node, mapped_child);
362 }
363 new_node
364 }
365
366 Tree {
367 root: map_node(&self.root, &f),
368 version: Cell::new(0),
369 }
370 }
371
372 pub fn find_all<F>(&self, predicate: F) -> Vec<NodeRef<T>>
374 where
375 F: Fn(&T) -> bool,
376 {
377 let mut result = Vec::new();
378 self.traverse(|node| {
379 if predicate(&node.borrow().value) {
380 result.push(Rc::clone(node));
381 }
382 });
383 result
384 }
385}
386
387impl<T: Clone + Debug> Display for Tree<T> {
388 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
389 fn fmt_node<T: Clone + Debug>(
390 node: &NodeRef<T>,
391 f: &mut Formatter<'_>,
392 prefix: &str,
393 is_last: bool,
394 ) -> fmt::Result {
395 let n = node.borrow();
396 let connector = if prefix.is_empty() {
397 ""
398 } else if is_last {
399 "└── "
400 } else {
401 "├── "
402 };
403 writeln!(f, "{}{}{:?}", prefix, connector, n.value)?;
404 let child_count = n.children.len();
405 for (i, child) in n.children.iter().enumerate() {
406 let mut new_prefix = prefix.to_string();
407 new_prefix.push_str(if is_last { " " } else { "│ " });
408 fmt_node(child, f, &new_prefix, i == child_count - 1)?;
409 }
410 Ok(())
411 }
412 fmt_node(&self.root, f, "", true)
413 }
414}
415
416impl<T: Clone + Debug> Debug for Tree<T> {
417 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
418 write!(f, "{}", self)
419 }
420}
421
422#[cfg(test)]
423mod tests {
424 use super::*;
425
426 #[test]
427 fn append_child_reparents_and_prevents_cycles() {
428 let root = TreeNode::new("root");
429 let first = TreeNode::new("first");
430 let second = TreeNode::new("second");
431 TreeNode::add_child(&root, Rc::clone(&first));
432 TreeNode::add_child(&first, Rc::clone(&second));
433
434 assert!(TreeNode::append_child(&root, Rc::clone(&second)));
435 assert!(first.borrow().children().is_empty());
436 assert!(Rc::ptr_eq(&second.borrow().parent().unwrap(), &root));
437 assert!(!TreeNode::append_child(&second, Rc::clone(&root)));
438 }
439
440 #[test]
441 fn owner_document_is_kept_per_node_and_across_clones() {
442 let element = TreeNode::new("element");
443 assert_eq!(element.borrow().owner_document(), None);
445
446 element.borrow().set_owner_document(7);
447 assert_eq!(element.borrow().owner_document(), Some(7));
448
449 let other = TreeNode::new("other");
452 TreeNode::add_child(&other, Rc::clone(&element));
453 assert_eq!(element.borrow().owner_document(), Some(7));
454
455 let clone = element.borrow().clone_node(true);
457 assert_eq!(clone.borrow().owner_document(), Some(7));
458 }
459
460 #[test]
461 fn detach_and_clear_children_reset_parent_links() {
462 let root = TreeNode::new("root");
463 let first = TreeNode::new("first");
464 let second = TreeNode::new("second");
465 TreeNode::add_child(&root, Rc::clone(&first));
466 TreeNode::add_child(&root, Rc::clone(&second));
467
468 assert!(TreeNode::detach(&first));
469 assert!(first.borrow().parent().is_none());
470 root.borrow_mut().clear_children();
471 assert!(second.borrow().parent().is_none());
472 }
473
474 #[test]
475 fn insert_before_moves_nodes_and_preserves_order() {
476 let root = TreeNode::new("root");
477 let first = TreeNode::new("first");
478 let second = TreeNode::new("second");
479 let moving = TreeNode::new("moving");
480 TreeNode::add_child(&root, Rc::clone(&first));
481 TreeNode::add_child(&root, Rc::clone(&second));
482 TreeNode::add_child(&first, Rc::clone(&moving));
483
484 assert!(TreeNode::insert_before(&root, Rc::clone(&moving), &second));
485 let children = root.borrow().children().to_vec();
486 assert!(Rc::ptr_eq(&children[0], &first));
487 assert!(Rc::ptr_eq(&children[1], &moving));
488 assert!(Rc::ptr_eq(&children[2], &second));
489 assert!(first.borrow().children().is_empty());
490 }
491}