1use std::sync::Arc;
2use std::{ops::Index, num::NonZeroUsize};
3use std::hash::{Hash, Hasher};
4use std::collections::hash_map::DefaultHasher;
5use im::Vector;
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8use once_cell::sync::Lazy;
9use parking_lot::RwLock;
10use lru::LruCache;
11use std::fmt::{self, Debug};
12use crate::error::PoolResult;
13use crate::node_type::NodeEnum;
14use crate::{
15 error::error_helpers,
16 mark::Mark,
17 node::Node,
18 ops::{AttrsRef, MarkRef, NodeRef},
19 types::NodeId,
20};
21
22static SHARD_INDEX_CACHE: Lazy<RwLock<LruCache<String, usize>>> =
24 Lazy::new(|| RwLock::new(LruCache::new(NonZeroUsize::new(10000).unwrap())));
25
26#[derive(Clone, PartialEq, Serialize, Deserialize)]
27pub struct Tree {
28 pub root_id: NodeId,
29 pub nodes: Vector<im::HashMap<NodeId, Arc<Node>>>, pub parent_map: im::HashMap<NodeId, NodeId>,
31 #[serde(skip)]
32 num_shards: usize, }
34impl Debug for Tree {
35 fn fmt(
36 &self,
37 f: &mut fmt::Formatter<'_>,
38 ) -> fmt::Result {
39 let nodes = self
41 .nodes
42 .iter()
43 .filter(|node| !node.is_empty())
44 .collect::<Vec<_>>();
45 f.debug_struct("Tree")
46 .field("root_id", &self.root_id)
47 .field("nodes", &nodes)
48 .field("parent_map", &self.parent_map)
49 .field("num_shards", &self.num_shards)
50 .finish()
51 }
52}
53
54impl Tree {
55 #[inline]
56 pub fn get_shard_index(
57 &self,
58 id: &NodeId,
59 ) -> usize {
60 {
62 let cache = SHARD_INDEX_CACHE.read();
63 if let Some(&index) = cache.peek(id) {
64 return index;
65 }
66 }
67
68 let mut hasher = DefaultHasher::new();
70 id.hash(&mut hasher);
71 let index = (hasher.finish() as usize) % self.num_shards;
72
73 {
75 let mut cache = SHARD_INDEX_CACHE.write();
76 cache.put(id.clone(), index);
77 }
78
79 index
80 }
81
82 #[inline]
83 pub fn get_shard_indices(
84 &self,
85 ids: &[&NodeId],
86 ) -> Vec<usize> {
87 ids.iter().map(|id| self.get_shard_index(id)).collect()
88 }
89
90 #[inline]
92 pub fn get_shard_index_batch<'a>(
93 &self,
94 ids: &'a [&'a NodeId],
95 ) -> Vec<(usize, &'a NodeId)> {
96 let mut results = Vec::with_capacity(ids.len());
97 let mut cache_misses = Vec::new();
98
99 {
101 let cache = SHARD_INDEX_CACHE.read();
102 for &id in ids {
103 if let Some(&index) = cache.peek(id) {
104 results.push((index, id));
105 } else {
106 cache_misses.push(id);
107 }
108 }
109 }
110
111 if !cache_misses.is_empty() {
113 let mut cache = SHARD_INDEX_CACHE.write();
114 for &id in &cache_misses {
115 let mut hasher = DefaultHasher::new();
116 id.hash(&mut hasher);
117 let index = (hasher.finish() as usize) % self.num_shards;
118 cache.put(id.clone(), index);
119 results.push((index, id));
120 }
121 }
122
123 results
124 }
125
126 pub fn clear_shard_cache() {
128 let mut cache = SHARD_INDEX_CACHE.write();
129 cache.clear();
130 }
131
132 pub fn contains_node(
133 &self,
134 id: &NodeId,
135 ) -> bool {
136 let shard_index = self.get_shard_index(id);
137 self.nodes[shard_index].contains_key(id)
138 }
139
140 pub fn get_node(
141 &self,
142 id: &NodeId,
143 ) -> Option<Arc<Node>> {
144 let shard_index = self.get_shard_index(id);
145 self.nodes[shard_index].get(id).cloned()
146 }
147
148 pub fn get_parent_node(
149 &self,
150 id: &NodeId,
151 ) -> Option<Arc<Node>> {
152 self.parent_map.get(id).and_then(|parent_id| {
153 let shard_index = self.get_shard_index(parent_id);
154 self.nodes[shard_index].get(parent_id).cloned()
155 })
156 }
157 pub fn from(nodes: NodeEnum) -> Self {
158 let num_shards = std::cmp::max(
159 std::thread::available_parallelism()
160 .map(NonZeroUsize::get)
161 .unwrap_or(2),
162 2,
163 );
164 let mut shards = Vector::from(vec![im::HashMap::new(); num_shards]);
165 let mut parent_map = im::HashMap::new();
166 let (root_node, children) = nodes.into_parts();
167 let root_id = root_node.id.clone();
168
169 let mut hasher = DefaultHasher::new();
170 root_id.hash(&mut hasher);
171 let shard_index = (hasher.finish() as usize) % num_shards;
172 shards[shard_index] =
173 shards[shard_index].update(root_id.clone(), Arc::new(root_node));
174
175 fn process_children(
176 children: Vec<NodeEnum>,
177 parent_id: &NodeId,
178 shards: &mut Vector<im::HashMap<NodeId, Arc<Node>>>,
179 parent_map: &mut im::HashMap<NodeId, NodeId>,
180 num_shards: usize,
181 ) {
182 for child in children {
183 let (node, grand_children) = child.into_parts();
184 let node_id = node.id.clone();
185 let mut hasher = DefaultHasher::new();
186 node_id.hash(&mut hasher);
187 let shard_index = (hasher.finish() as usize) % num_shards;
188 shards[shard_index] =
189 shards[shard_index].update(node_id.clone(), Arc::new(node));
190 parent_map.insert(node_id.clone(), parent_id.clone());
191
192 process_children(
194 grand_children,
195 &node_id,
196 shards,
197 parent_map,
198 num_shards,
199 );
200 }
201 }
202
203 process_children(
204 children,
205 &root_id,
206 &mut shards,
207 &mut parent_map,
208 num_shards,
209 );
210
211 Self { root_id, nodes: shards, parent_map, num_shards }
212 }
213
214 pub fn new(root: Node) -> Self {
215 let num_shards = std::cmp::max(
216 std::thread::available_parallelism()
217 .map(NonZeroUsize::get)
218 .unwrap_or(2),
219 2,
220 );
221 let mut nodes = Vector::from(vec![im::HashMap::new(); num_shards]);
222 let root_id = root.id.clone();
223 let mut hasher = DefaultHasher::new();
224 root_id.hash(&mut hasher);
225 let shard_index = (hasher.finish() as usize) % num_shards;
226 nodes[shard_index] =
227 nodes[shard_index].update(root_id.clone(), Arc::new(root));
228 Self { root_id, nodes, parent_map: im::HashMap::new(), num_shards }
229 }
230
231 pub fn update_attr(
232 &mut self,
233 id: &NodeId,
234 new_values: im::HashMap<String, Value>,
235 ) -> PoolResult<()> {
236 let shard_index = self.get_shard_index(id);
237 let node = self.nodes[shard_index]
238 .get(id)
239 .ok_or(error_helpers::node_not_found(id.clone()))?;
240 let new_node = node.as_ref().update_attr(new_values);
241 self.nodes[shard_index] =
242 self.nodes[shard_index].update(id.clone(), Arc::new(new_node));
243 Ok(())
244 }
245 pub fn update_node(
246 &mut self,
247 node: Node,
248 ) -> PoolResult<()> {
249 let shard_index = self.get_shard_index(&node.id);
250 self.nodes[shard_index] =
251 self.nodes[shard_index].update(node.id.clone(), Arc::new(node));
252 Ok(())
253 }
254
255 pub fn add(
266 &mut self,
267 parent_id: &NodeId,
268 nodes: Vec<NodeEnum>,
269 ) -> PoolResult<()> {
270 let parent_shard_index = self.get_shard_index(&parent_id);
272 let parent_node = self.nodes[parent_shard_index]
273 .get(parent_id)
274 .ok_or(error_helpers::parent_not_found(parent_id.clone()))?;
275 let mut new_parent = parent_node.as_ref().clone();
276
277 let zenliang: Vector<String> =
279 nodes.iter().map(|n| n.0.id.clone()).collect();
280 let mut new_content = im::Vector::new();
282 for id in zenliang {
283 if !new_parent.content.contains(&id) {
284 new_content.push_back(id);
285 }
286 }
287 new_parent.content.extend(new_content);
288
289 self.nodes[parent_shard_index] = self.nodes[parent_shard_index]
291 .update(parent_id.clone(), Arc::new(new_parent));
292
293 let mut node_queue = Vec::new();
295 node_queue.push((nodes, parent_id.clone()));
296 while let Some((current_children, current_parent_id)) = node_queue.pop()
297 {
298 for child in current_children {
299 let (mut child_node, grand_children) = child.into_parts();
301 let current_node_id = child_node.id.clone();
302
303 let grand_children_ids: Vector<String> =
305 grand_children.iter().map(|n| n.0.id.clone()).collect();
306 let mut new_content = im::Vector::new();
307 for id in grand_children_ids {
308 if !child_node.content.contains(&id) {
309 new_content.push_back(id);
310 }
311 }
312 child_node.content.extend(new_content);
313
314 let shard_index = self.get_shard_index(¤t_node_id);
316 self.nodes[shard_index] = self.nodes[shard_index]
317 .update(current_node_id.clone(), Arc::new(child_node));
318
319 self.parent_map
321 .insert(current_node_id.clone(), current_parent_id.clone());
322
323 node_queue.push((grand_children, current_node_id.clone()));
325 }
326 }
327 Ok(())
328 }
329 pub fn add_at_index(
331 &mut self,
332 parent_id: &NodeId,
333 index: usize,
334 node: &Node,
335 ) -> PoolResult<()> {
336 let parent_shard_index = self.get_shard_index(parent_id);
338 let parent = self.nodes[parent_shard_index]
339 .get(parent_id)
340 .ok_or(error_helpers::parent_not_found(parent_id.clone()))?;
341 let new_parent = parent.as_ref().insert_content_at_index(index, &node.id);
342 self.nodes[parent_shard_index] = self.nodes[parent_shard_index]
344 .update(parent_id.clone(), Arc::new(new_parent));
345 self.parent_map.insert(node.id.clone(), parent_id.clone());
347 let shard_index = self.get_shard_index(&node.id);
349 self.nodes[shard_index] = self.nodes[shard_index]
350 .update(node.id.clone(), Arc::new(node.clone()));
351 Ok(())
352 }
353 pub fn add_node(
354 &mut self,
355 parent_id: &NodeId,
356 nodes: &Vec<Node>,
357 ) -> PoolResult<()> {
358 let parent_shard_index = self.get_shard_index(parent_id);
359 let parent = self.nodes[parent_shard_index]
360 .get(parent_id)
361 .ok_or(error_helpers::parent_not_found(parent_id.clone()))?;
362 let node_ids = nodes.iter().map(|n| n.id.clone()).collect();
363 let new_parent = parent.as_ref().insert_contents(&node_ids);
365
366 self.nodes[parent_shard_index] = self.nodes[parent_shard_index]
368 .update(parent_id.clone(), Arc::new(new_parent));
369
370 for node in nodes {
372 self.parent_map.insert(node.id.clone(), parent_id.clone());
374
375 for child_id in &node.content {
377 self.parent_map.insert(child_id.clone(), node.id.clone());
378 }
379
380 let shard_index = self.get_shard_index(&node.id);
382 self.nodes[shard_index] = self.nodes[shard_index]
383 .update(node.id.clone(), Arc::new(node.clone()));
384 }
385 Ok(())
386 }
387
388 pub fn node(
389 &mut self,
390 key: &str,
391 ) -> NodeRef<'_> {
392 NodeRef::new(self, key.to_string())
393 }
394 pub fn mark(
395 &mut self,
396 key: &str,
397 ) -> MarkRef<'_> {
398 MarkRef::new(self, key.to_string())
399 }
400 pub fn attrs(
401 &mut self,
402 key: &str,
403 ) -> AttrsRef<'_> {
404 AttrsRef::new(self, key.to_string())
405 }
406
407 pub fn children(
408 &self,
409 parent_id: &NodeId,
410 ) -> Option<im::Vector<NodeId>> {
411 self.get_node(parent_id).map(|n| n.content.clone())
412 }
413
414 pub fn children_node(
415 &self,
416 parent_id: &NodeId,
417 ) -> Option<im::Vector<Arc<Node>>> {
418 self.children(parent_id)
419 .map(|ids| ids.iter().filter_map(|id| self.get_node(id)).collect())
420 }
421 pub fn all_children(
423 &self,
424 parent_id: &NodeId,
425 filter: Option<&dyn Fn(&Node) -> bool>,
426 ) -> Option<NodeEnum> {
427 if let Some(node) = self.get_node(parent_id) {
428 let mut child_enums = Vec::new();
429 for child_id in &node.content {
430 if let Some(child_node) = self.get_node(child_id) {
431 if let Some(filter_fn) = filter {
433 if !filter_fn(child_node.as_ref()) {
434 continue; }
436 }
437 if let Some(child_enum) =
439 self.all_children(child_id, filter)
440 {
441 child_enums.push(child_enum);
442 }
443 }
444 }
445 Some(NodeEnum(node.as_ref().clone(), child_enums))
446 } else {
447 None
448 }
449 }
450
451 pub fn children_count(
452 &self,
453 parent_id: &NodeId,
454 ) -> usize {
455 self.get_node(parent_id).map(|n| n.content.len()).unwrap_or(0)
456 }
457 pub fn remove_mark_by_name(
458 &mut self,
459 id: &NodeId,
460 mark_name: &str,
461 ) -> PoolResult<()> {
462 let shard_index = self.get_shard_index(id);
463 let node = self.nodes[shard_index]
464 .get(id)
465 .ok_or(error_helpers::node_not_found(id.clone()))?;
466 let new_node = node.as_ref().remove_mark_by_name(mark_name);
467 self.nodes[shard_index] =
468 self.nodes[shard_index].update(id.clone(), Arc::new(new_node));
469 Ok(())
470 }
471 pub fn get_marks(
472 &self,
473 id: &NodeId,
474 ) -> Option<im::Vector<Mark>> {
475 self.get_node(id).map(|n| n.marks.clone())
476 }
477
478 pub fn remove_mark(
479 &mut self,
480 id: &NodeId,
481 mark_types: &[String],
482 ) -> PoolResult<()> {
483 let shard_index = self.get_shard_index(id);
484 let node = self.nodes[shard_index]
485 .get(id)
486 .ok_or(error_helpers::node_not_found(id.clone()))?;
487 let new_node = node.as_ref().remove_mark(mark_types);
488 self.nodes[shard_index] =
489 self.nodes[shard_index].update(id.clone(), Arc::new(new_node));
490 Ok(())
491 }
492
493 pub fn add_mark(
494 &mut self,
495 id: &NodeId,
496 marks: &Vec<Mark>,
497 ) -> PoolResult<()> {
498 let shard_index = self.get_shard_index(id);
499 let node = self.nodes[shard_index]
500 .get(id)
501 .ok_or(error_helpers::node_not_found(id.clone()))?;
502 let new_node = node.as_ref().add_marks(marks);
503 self.nodes[shard_index] =
504 self.nodes[shard_index].update(id.clone(), Arc::new(new_node));
505 Ok(())
506 }
507
508 pub fn move_node(
509 &mut self,
510 source_parent_id: &NodeId,
511 target_parent_id: &NodeId,
512 node_id: &NodeId,
513 position: Option<usize>,
514 ) -> PoolResult<()> {
515 let source_shard_index = self.get_shard_index(source_parent_id);
516 let target_shard_index = self.get_shard_index(target_parent_id);
517 let node_shard_index = self.get_shard_index(node_id);
518 let source_parent = self.nodes[source_shard_index]
519 .get(source_parent_id)
520 .ok_or(error_helpers::parent_not_found(source_parent_id.clone()))?;
521 let target_parent = self.nodes[target_shard_index]
522 .get(target_parent_id)
523 .ok_or(error_helpers::parent_not_found(target_parent_id.clone()))?;
524 let _node = self.nodes[node_shard_index]
525 .get(node_id)
526 .ok_or(error_helpers::node_not_found(node_id.clone()))?;
527 if !source_parent.content.contains(node_id) {
528 return Err(error_helpers::invalid_parenting(
529 node_id.clone(),
530 source_parent_id.clone(),
531 ));
532 }
533 let mut new_source_parent = source_parent.as_ref().clone();
534 new_source_parent.content = new_source_parent
535 .content
536 .iter()
537 .filter(|&id| id != node_id)
538 .cloned()
539 .collect();
540 let mut new_target_parent = target_parent.as_ref().clone();
541 if let Some(pos) = position {
542 let insert_pos = pos.min(new_target_parent.content.len());
544
545 new_target_parent.content.insert(insert_pos, node_id.clone());
547 } else {
548 new_target_parent.content.push_back(node_id.clone());
550 }
551 self.nodes[source_shard_index] = self.nodes[source_shard_index]
552 .update(source_parent_id.clone(), Arc::new(new_source_parent));
553 self.nodes[target_shard_index] = self.nodes[target_shard_index]
554 .update(target_parent_id.clone(), Arc::new(new_target_parent));
555 self.parent_map.insert(node_id.clone(), target_parent_id.clone());
556 Ok(())
557 }
558
559 pub fn remove_node(
560 &mut self,
561 parent_id: &NodeId,
562 nodes: Vec<NodeId>,
563 ) -> PoolResult<()> {
564 let parent_shard_index = self.get_shard_index(parent_id);
565 let parent = self.nodes[parent_shard_index]
566 .get(parent_id)
567 .ok_or(error_helpers::parent_not_found(parent_id.clone()))?;
568 if nodes.contains(&self.root_id) {
569 return Err(error_helpers::cannot_remove_root());
570 }
571 for node_id in &nodes {
572 if !parent.content.contains(node_id) {
573 return Err(error_helpers::invalid_parenting(
574 node_id.clone(),
575 parent_id.clone(),
576 ));
577 }
578 }
579 let nodes_to_remove: std::collections::HashSet<_> =
580 nodes.iter().collect();
581 let filtered_children: im::Vector<NodeId> = parent
582 .as_ref()
583 .content
584 .iter()
585 .filter(|&id| !nodes_to_remove.contains(id))
586 .cloned()
587 .collect();
588 let mut parent_node = parent.as_ref().clone();
589 parent_node.content = filtered_children;
590 self.nodes[parent_shard_index] = self.nodes[parent_shard_index]
591 .update(parent_id.clone(), Arc::new(parent_node));
592 let mut remove_nodes = Vec::new();
593 for node_id in nodes {
594 self.remove_subtree(&node_id, &mut remove_nodes)?;
595 }
596 Ok(())
597 }
598 pub fn remove_node_by_id(
600 &mut self,
601 node_id: &NodeId,
602 ) -> PoolResult<()> {
603 if node_id == &self.root_id {
605 return Err(error_helpers::cannot_remove_root());
606 }
607
608 let shard_index = self.get_shard_index(node_id);
609 let _ = self.nodes[shard_index]
610 .get(node_id)
611 .ok_or(error_helpers::node_not_found(node_id.clone()))?;
612
613 if let Some(parent_id) = self.parent_map.get(node_id).cloned() {
615 let parent_shard_index = self.get_shard_index(&parent_id);
616 if let Some(parent_node) =
617 self.nodes[parent_shard_index].get(&parent_id)
618 {
619 let mut new_parent = parent_node.as_ref().clone();
620 new_parent.content = new_parent
621 .content
622 .iter()
623 .filter(|&id| id != node_id)
624 .cloned()
625 .collect();
626 self.nodes[parent_shard_index] = self.nodes[parent_shard_index]
627 .update(parent_id.clone(), Arc::new(new_parent));
628 }
629 }
630
631 let mut remove_nodes = Vec::new();
633 self.remove_subtree(node_id, &mut remove_nodes)?;
634
635 Ok(())
637 }
638
639 pub fn remove_node_by_index(
641 &mut self,
642 parent_id: &NodeId,
643 index: usize,
644 ) -> PoolResult<()> {
645 let shard_index = self.get_shard_index(parent_id);
646 let parent = self.nodes[shard_index]
647 .get(parent_id)
648 .ok_or(error_helpers::parent_not_found(parent_id.clone()))?;
649 let mut new_parent = parent.as_ref().clone();
650 let remove_node_id = new_parent.content.remove(index);
651 self.nodes[shard_index] = self.nodes[shard_index]
652 .update(parent_id.clone(), Arc::new(new_parent));
653 let mut remove_nodes = Vec::new();
654 self.remove_subtree(&remove_node_id, &mut remove_nodes)?;
655 Ok(())
656 }
657
658 fn remove_subtree(
660 &mut self,
661 node_id: &NodeId,
662 remove_nodes: &mut Vec<Node>,
663 ) -> PoolResult<()> {
664 if node_id == &self.root_id {
665 return Err(error_helpers::cannot_remove_root());
666 }
667 let shard_index = self.get_shard_index(node_id);
668 let _ = self.nodes[shard_index]
669 .get(node_id)
670 .ok_or(error_helpers::node_not_found(node_id.clone()))?;
671 if let Some(children) = self.children(node_id) {
672 for child_id in children {
673 self.remove_subtree(&child_id, remove_nodes)?;
674 }
675 }
676 self.parent_map.remove(node_id);
677 if let Some(remove_node) = self.nodes[shard_index].remove(node_id) {
678 remove_nodes.push(remove_node.as_ref().clone());
679 }
680 Ok(())
681 }
682}
683
684impl Index<&NodeId> for Tree {
685 type Output = Arc<Node>;
686 fn index(
687 &self,
688 index: &NodeId,
689 ) -> &Self::Output {
690 let shard_index = self.get_shard_index(index);
691 self.nodes[shard_index].get(index).expect("Node not found")
692 }
693}
694
695impl Index<&str> for Tree {
696 type Output = Arc<Node>;
697 fn index(
698 &self,
699 index: &str,
700 ) -> &Self::Output {
701 let node_id = NodeId::from(index);
702 let shard_index = self.get_shard_index(&node_id);
703 self.nodes[shard_index].get(&node_id).expect("Node not found")
704 }
705}
706
707#[cfg(test)]
708mod tests {
709 use super::*;
710 use crate::node::Node;
711 use crate::attrs::Attrs;
712 use crate::mark::Mark;
713 use im::HashMap;
714 use serde_json::json;
715
716 fn create_test_node(id: &str) -> Node {
717 Node::new(id, "test".to_string(), Attrs::default(), vec![], vec![])
718 }
719
720 #[test]
721 fn test_tree_creation() {
722 let root = create_test_node("root");
723 let tree = Tree::new(root.clone());
724 assert_eq!(tree.root_id, root.id);
725 assert!(tree.contains_node(&root.id));
726 }
727
728 #[test]
729 fn test_add_node() {
730 let root = create_test_node("root");
731 let mut tree = Tree::new(root.clone());
732
733 let child = create_test_node("child");
734 let nodes = vec![child.clone()];
735
736 tree.add_node(&root.id, &nodes).unwrap();
737 dbg!(&tree);
738 assert!(tree.contains_node(&child.id));
739 assert_eq!(tree.children(&root.id).unwrap().len(), 1);
740 }
741
742 #[test]
743 fn test_remove_node() {
744 let root = create_test_node("root");
745 let mut tree = Tree::new(root.clone());
746
747 let child = create_test_node("child");
748 let nodes = vec![child.clone()];
749
750 tree.add_node(&root.id, &nodes).unwrap();
751 dbg!(&tree);
752 tree.remove_node(&root.id, vec![child.id.clone()]).unwrap();
753 dbg!(&tree);
754 assert!(!tree.contains_node(&child.id));
755 assert_eq!(tree.children(&root.id).unwrap().len(), 0);
756 }
757
758 #[test]
759 fn test_move_node() {
760 let parent1 = create_test_node("parent1");
762 let parent2 = create_test_node("parent2");
763 let mut tree = Tree::new(parent1.clone());
764
765 tree.add_node(&parent1.id, &vec![parent2.clone()]).unwrap();
767
768 let child1 = create_test_node("child1");
770 let child2 = create_test_node("child2");
771 let child3 = create_test_node("child3");
772
773 tree.add_node(&parent1.id, &vec![child1.clone()]).unwrap();
775 tree.add_node(&parent1.id, &vec![child2.clone()]).unwrap();
776 tree.add_node(&parent1.id, &vec![child3.clone()]).unwrap();
777
778 let parent1_children = tree.children(&parent1.id).unwrap();
780 assert_eq!(parent1_children.len(), 4); assert_eq!(parent1_children[0], parent2.id);
782 assert_eq!(parent1_children[1], child1.id);
783 assert_eq!(parent1_children[2], child2.id);
784 assert_eq!(parent1_children[3], child3.id);
785
786 tree.move_node(&parent1.id, &parent2.id, &child1.id, None).unwrap();
788
789 let parent1_children = tree.children(&parent1.id).unwrap();
791 let parent2_children = tree.children(&parent2.id).unwrap();
792 assert_eq!(parent1_children.len(), 3); assert_eq!(parent2_children.len(), 1); assert_eq!(parent2_children[0], child1.id);
795
796 tree.move_node(&parent1.id, &parent2.id, &child2.id, Some(1)).unwrap();
798
799 let parent1_children = tree.children(&parent1.id).unwrap();
801 let parent2_children = tree.children(&parent2.id).unwrap();
802 assert_eq!(parent1_children.len(), 2); assert_eq!(parent2_children.len(), 2); assert_eq!(parent2_children[0], child1.id);
805 assert_eq!(parent2_children[1], child2.id);
806
807 let child1_parent = tree.get_parent_node(&child1.id).unwrap();
809 let child2_parent = tree.get_parent_node(&child2.id).unwrap();
810 assert_eq!(child1_parent.id, parent2.id);
811 assert_eq!(child2_parent.id, parent2.id);
812 }
813
814 #[test]
815 fn test_update_attr() {
816 let root = create_test_node("root");
817 let mut tree = Tree::new(root.clone());
818
819 let mut attrs = HashMap::new();
820 attrs.insert("key".to_string(), json!("value"));
821
822 tree.update_attr(&root.id, attrs).unwrap();
823
824 let node = tree.get_node(&root.id).unwrap();
825 dbg!(&node);
826 assert_eq!(node.attrs.get("key").unwrap(), &json!("value"));
827 }
828
829 #[test]
830 fn test_add_mark() {
831 let root = create_test_node("root");
832 let mut tree = Tree::new(root.clone());
833
834 let mark = Mark { r#type: "test".to_string(), attrs: Attrs::default() };
835 tree.add_mark(&root.id, &vec![mark.clone()]).unwrap();
836 dbg!(&tree);
837 let node = tree.get_node(&root.id).unwrap();
838 assert!(node.marks.contains(&mark));
839 }
840
841 #[test]
842 fn test_remove_mark() {
843 let root = create_test_node("root");
844 let mut tree = Tree::new(root.clone());
845
846 let mark = Mark { r#type: "test".to_string(), attrs: Attrs::default() };
847 tree.add_mark(&root.id, &vec![mark.clone()]).unwrap();
848 dbg!(&tree);
849 tree.remove_mark(&root.id, &[mark.r#type.clone()]).unwrap();
850 dbg!(&tree);
851 let node = tree.get_node(&root.id).unwrap();
852 assert!(!node.marks.iter().any(|m| m.r#type == mark.r#type));
853 }
854
855 #[test]
856 fn test_all_children() {
857 let root = create_test_node("root");
858 let mut tree = Tree::new(root.clone());
859
860 let child1 = create_test_node("child1");
861 let child2 = create_test_node("child2");
862
863 tree.add_node(&root.id, &vec![child1.clone()]).unwrap();
864 tree.add_node(&root.id, &vec![child2.clone()]).unwrap();
865 dbg!(&tree);
866 let all_children = tree.all_children(&root.id, None).unwrap();
867 assert_eq!(all_children.1.len(), 2);
868 }
869
870 #[test]
871 fn test_children_count() {
872 let root = create_test_node("root");
873 let mut tree = Tree::new(root.clone());
874
875 let child1 = create_test_node("child1");
876 let child2 = create_test_node("child2");
877
878 tree.add_node(&root.id, &vec![child1.clone()]).unwrap();
879 tree.add_node(&root.id, &vec![child2.clone()]).unwrap();
880
881 assert_eq!(tree.children_count(&root.id), 2);
882 }
883
884 #[test]
885 fn test_remove_node_by_id_updates_parent() {
886 let root = create_test_node("root");
887 let mut tree = Tree::new(root.clone());
888
889 let child = create_test_node("child");
890 tree.add_node(&root.id, &vec![child.clone()]).unwrap();
891
892 assert_eq!(tree.children_count(&root.id), 1);
894 assert!(tree.contains_node(&child.id));
895
896 tree.remove_node_by_id(&child.id).unwrap();
898
899 assert_eq!(tree.children_count(&root.id), 0);
901 assert!(!tree.contains_node(&child.id));
902 }
903
904 #[test]
905 fn test_move_node_position_edge_cases() {
906 let root = create_test_node("root");
907 let mut tree = Tree::new(root.clone());
908
909 let container = create_test_node("container");
910 tree.add_node(&root.id, &vec![container.clone()]).unwrap();
911
912 let child1 = create_test_node("child1");
913 let child2 = create_test_node("child2");
914 let child3 = create_test_node("child3");
915
916 tree.add_node(&root.id, &vec![child1.clone()]).unwrap();
917 tree.add_node(&root.id, &vec![child2.clone()]).unwrap();
918 tree.add_node(&root.id, &vec![child3.clone()]).unwrap();
919
920 tree.move_node(&root.id, &container.id, &child1.id, Some(100)).unwrap();
922
923 let container_children = tree.children(&container.id).unwrap();
924 assert_eq!(container_children.len(), 1);
925 assert_eq!(container_children[0], child1.id);
926
927 tree.move_node(&root.id, &container.id, &child2.id, Some(0)).unwrap();
929
930 let container_children = tree.children(&container.id).unwrap();
931 assert_eq!(container_children.len(), 2);
932 assert_eq!(container_children[0], child2.id);
933 assert_eq!(container_children[1], child1.id);
934 }
935
936 #[test]
937 fn test_cannot_remove_root_node() {
938 let root = create_test_node("root");
939 let mut tree = Tree::new(root.clone());
940
941 let result = tree.remove_node_by_id(&root.id);
943 assert!(result.is_err());
944 }
945
946 #[test]
947 fn test_get_parent_node() {
948 let root = create_test_node("root");
949 let mut tree = Tree::new(root.clone());
950
951 let child = create_test_node("child");
952 tree.add_node(&root.id, &vec![child.clone()]).unwrap();
953
954 let parent = tree.get_parent_node(&child.id).unwrap();
955 assert_eq!(parent.id, root.id);
956 }
957}