1use std::collections::{BTreeMap, BTreeSet};
12
13use snafu::Snafu;
14use uuid::Uuid;
15
16#[cfg(feature = "serde")]
17use crate::serde_utils::*;
18use crate::{Aggregate, Meta, Metadata};
19
20#[derive(Clone, Debug, Snafu)]
22#[snafu(visibility(pub(crate)))]
23pub enum NodeStoreError {
24 NodeNotInStore { id: Uuid },
26 BusWithoutParent { id: Uuid },
28 CyclicAscendants { id: Uuid },
30 CyclicDescendants { id: Uuid },
32}
33
34#[derive(Clone, Debug, Default, PartialEq)]
36#[cfg_attr(
37 feature = "serde",
38 derive(serde::Serialize, serde::Deserialize),
39 serde(rename_all = "camelCase")
40)]
41pub struct Node {
42 pub metadata: Metadata,
44 #[cfg_attr(
46 feature = "serde",
47 serde(default, skip_serializing_if = "Option::is_none")
48 )]
49 pub parent: Option<Uuid>,
50 #[cfg_attr(
52 feature = "serde",
53 serde(default, skip_serializing_if = "is_empty_vec")
54 )]
55 pub children: Vec<Uuid>,
56 #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "is_default"))]
58 pub is_bus: bool,
59}
60impl Node {
61 pub fn new(
63 metadata: Option<Metadata>,
64 parent: Option<Uuid>,
65 children: Option<Vec<Uuid>>,
66 is_bus: Option<bool>,
67 ) -> Self {
68 Node {
69 metadata: metadata.unwrap_or_default(),
70 parent,
71 children: children.unwrap_or_default(),
72 is_bus: is_bus.unwrap_or(false),
73 }
74 }
75
76 pub fn is_root(&self) -> bool {
78 self.parent.is_none()
79 }
80
81 pub fn is_leaf(&self) -> bool {
83 self.children.is_empty()
84 }
85
86 pub fn dim(&self) -> usize {
88 self.children.len()
89 }
90}
91
92impl Meta for Node {
93 fn get_meta(&self) -> &Metadata {
95 &self.metadata
96 }
97}
98
99#[derive(Clone, Debug, Default, PartialEq)]
100#[cfg_attr(
101 feature = "serde",
102 derive(serde::Serialize, serde::Deserialize),
103 serde(default)
104)]
105pub struct NodeStoreData {
106 nodes: BTreeMap<Uuid, Node>,
107 roots: BTreeSet<Uuid>,
108 leafs: BTreeSet<Uuid>,
109 aggregate: Aggregate,
110 depth: Option<usize>,
111}
112impl HasNodeStore for NodeStoreData {
113 fn node_store(&self) -> &NodeStoreData {
115 self
116 }
117 fn node_store_mut(&mut self) -> &mut NodeStoreData {
119 self
120 }
121}
122impl NodeStore for NodeStoreData {}
123
124pub trait HasNodeStore {
125 fn node_store(&self) -> &NodeStoreData;
126 fn node_store_mut(&mut self) -> &mut NodeStoreData;
127}
128
129pub trait NodeStore: HasNodeStore {
130 fn nodes_len(&self) -> usize {
132 self.node_store().nodes.len()
133 }
134
135 fn max_node_depth(&mut self) -> usize
137 where
138 Self: Sized,
139 {
140 if let Some(depth) = self.node_store().depth {
141 return depth;
142 }
143 let depth = self.calculate_node_depth();
144 self.node_store_mut().depth = Some(depth);
145 depth
146 }
147
148 fn is_nodes_empty(&self) -> bool {
150 self.nodes_len() == 0
151 }
152
153 fn has_node(&self, id: &Uuid) -> bool {
155 self.node_store().nodes.contains_key(id)
156 }
157
158 fn add_node(&mut self, node: Node, safe: bool) -> Result<Option<Node>, NodeStoreError>
161 where
162 Self: Sized,
163 {
164 if safe {
165 self.check_node(&node)?;
166 }
167 let id = node.id().to_owned();
168 let replaced = self.del_node(&id);
169 self.node_store_mut().aggregate.add(node.get_meta());
170 if node.is_leaf() {
171 self.node_store_mut().leafs.insert(id);
172 }
173 if node.is_root() {
174 self.node_store_mut().roots.insert(id);
175 }
176 if node.parent.is_some() || !node.children.is_empty() {
177 self.node_store_mut().depth = None;
178 }
179 self.node_store_mut().nodes.insert(id, node);
180 Ok(replaced)
181 }
182
183 fn extend_nodes(&mut self, nodes: Vec<Node>, safe: bool) -> Result<Vec<Node>, NodeStoreError>
187 where
188 Self: Sized,
189 {
190 let mut replaced = vec![];
191 for node in nodes.clone().into_iter() {
192 if let Some(node) = self.add_node(node, false)? {
193 replaced.push(node);
194 }
195 }
196 if safe {
197 for node in nodes.iter() {
199 let node_id = node.id();
200 for child_id in node.children.iter() {
201 if let Some(child) = self.get_node(child_id)
202 && child.parent.as_ref() != Some(node_id)
203 {
204 self.set_parent(child_id, Some(node_id))?;
205 }
206 }
207 if let Some(parent_id) = node.parent.as_ref()
208 && let Some(parent) = self.get_node(parent_id)
209 && !parent.children.contains(node_id)
210 {
211 self.set_parent(node_id, Some(parent_id))?;
212 }
213 }
214 for node in nodes.iter() {
216 self.check_node(self.get_node_err(node.id())?)?;
217 }
218 }
219 Ok(replaced)
220 }
221
222 fn check_node(&self, node: &Node) -> Result<(), NodeStoreError>
225 where
226 Self: Sized,
227 {
228 if let Some(parent_id) = &node.parent
229 && !self.has_node(parent_id)
230 {
231 return NodeNotInStoreSnafu {
232 id: parent_id.to_owned(),
233 }
234 .fail();
235 }
236 for child_id in node.children.iter() {
237 if !self.has_node(child_id) {
238 return NodeNotInStoreSnafu {
239 id: child_id.to_owned(),
240 }
241 .fail();
242 }
243 }
244 if node.is_bus && node.parent.is_none() {
245 return BusWithoutParentSnafu {
246 id: node.id().to_owned(),
247 }
248 .fail();
249 }
250 self.ascendant_nodes(node.id(), true, true, None, None)
253 .try_fold((), |_, r| r.map(|_| ()))?;
254 self.descendant_nodes(node.id(), true, true, None, None)
255 .try_fold((), |_, r| r.map(|_| ()))?;
256 Ok(())
257 }
258
259 fn get_node(&self, id: &Uuid) -> Option<&Node> {
261 self.node_store().nodes.get(id)
262 }
263 fn get_node_err(&self, id: &Uuid) -> Result<&Node, NodeStoreError> {
265 match self.node_store().nodes.get(id) {
266 Some(node) => Ok(node),
267 None => Err(NodeStoreError::NodeNotInStore { id: id.to_owned() }),
268 }
269 }
270
271 fn get_node_mut(&mut self, node_id: &Uuid) -> Option<&mut Node> {
273 self.node_store_mut().nodes.get_mut(node_id)
274 }
275
276 fn del_node(&mut self, node_id: &Uuid) -> Option<Node> {
278 let store = self.node_store_mut();
279 let deleted = store.nodes.remove(node_id);
280 if let Some(deleted) = deleted.as_ref() {
281 store.aggregate.subtract(deleted.get_meta());
282 store.roots.remove(node_id);
283 store.leafs.remove(node_id);
284 store.depth = None;
285 }
286 deleted
287 }
288
289 fn calculate_node_depth(&self) -> usize
291 where
292 Self: Sized,
293 {
294 self.leaf_ids()
295 .filter_map(|id| self.node_depth(&id, false, None, None).ok())
296 .max()
297 .unwrap_or(0)
298 }
299
300 fn all_node_ids(&self) -> impl Iterator<Item = Uuid> {
302 self.node_store().nodes.keys().copied()
303 }
304
305 fn all_nodes(&self) -> impl Iterator<Item = &Node> {
307 self.node_store().nodes.values()
308 }
309
310 fn root_ids(&self) -> impl Iterator<Item = Uuid> {
312 self.node_store().roots.iter().copied()
313 }
314
315 fn root_nodes(&self) -> impl Iterator<Item = &Node> {
317 self.node_store()
318 .roots
319 .iter()
320 .filter_map(|id| self.get_node(id))
321 }
322
323 fn leaf_ids(&self) -> impl Iterator<Item = Uuid> {
325 self.node_store().leafs.iter().copied()
326 }
327
328 fn leaf_nodes(&self) -> impl Iterator<Item = &Node> {
330 self.node_store()
331 .leafs
332 .iter()
333 .filter_map(|id| self.get_node(id))
334 }
335
336 fn set_parent(
340 &mut self,
341 child_id: &Uuid,
342 parent_id: Option<&Uuid>,
343 ) -> Result<(), NodeStoreError> {
344 if let Some(child) = self.get_node(child_id) {
346 if let Some(current_parent_id) = child.parent {
347 let add_to_leafs = {
348 if let Some(current_parent) = self.get_node_mut(¤t_parent_id) {
349 current_parent.children.retain(|x| x != child_id);
350 current_parent.is_leaf()
351 } else {
352 false
353 }
354 };
355 if add_to_leafs {
356 self.node_store_mut().leafs.insert(current_parent_id);
357 }
358 }
359 } else {
360 return Err(NodeStoreError::NodeNotInStore {
361 id: child_id.to_owned(),
362 });
363 }
364
365 if let Some(parent_id) = parent_id {
367 if self.has_node(parent_id) {
368 if let Some(child) = self.get_node_mut(child_id) {
369 child.parent = Some(parent_id.to_owned());
370 self.node_store_mut().roots.remove(child_id);
371 }
372 if let Some(parent) = self.get_node_mut(parent_id) {
373 if !parent.children.contains(child_id) {
374 parent.children.push(child_id.to_owned())
375 };
376 self.node_store_mut().leafs.remove(parent_id);
377 }
378 } else {
379 return Err(NodeStoreError::NodeNotInStore {
380 id: parent_id.to_owned(),
381 });
382 }
383 } else if let Some(child) = self.get_node_mut(child_id) {
384 child.parent = None;
385 child.is_bus = false;
386 self.node_store_mut().roots.insert(*child_id);
387 }
388 self.node_store_mut().depth = None;
389 Ok(())
390 }
391
392 fn set_bus(&mut self, node_id: &Uuid, is_bus: bool) -> Result<(), NodeStoreError> {
394 if let Some(node) = self.get_node_mut(node_id) {
395 if is_bus && node.parent.is_none() {
396 return Err(NodeStoreError::BusWithoutParent {
397 id: node_id.to_owned(),
398 });
399 }
400 node.is_bus = is_bus;
401 } else {
402 return Err(NodeStoreError::NodeNotInStore {
403 id: node_id.to_owned(),
404 });
405 }
406 Ok(())
407 }
408
409 fn bus_ids(&self, parent_id: &Uuid) -> Result<impl Iterator<Item = Uuid>, NodeStoreError> {
411 Ok(self.bus_nodes(parent_id)?.map(|node| node.id()).copied())
412 }
413
414 fn bus_nodes(&self, parent_id: &Uuid) -> Result<impl Iterator<Item = &Node>, NodeStoreError> {
416 self.get_node_err(parent_id).map(|parent| {
417 parent.children.iter().filter_map(|id| {
418 let node = self.get_node(id)?;
419 if node.is_bus { Some(node) } else { None }
420 })
421 })
422 }
423
424 fn ascendant_ids<'a, 'n>(
430 &'n self,
431 node_id: &'a Uuid,
432 safe: bool,
433 only_root: bool,
434 root_ids: Option<&'a BTreeSet<Uuid>>,
435 height: Option<usize>,
436 ) -> impl Iterator<Item = Result<&'n Uuid, NodeStoreError>>
437 where
438 Self: Sized,
439 {
440 AscendantIterator::new(self, node_id, safe, only_root, root_ids, height)
441 }
442
443 fn ascendant_nodes<'a, 'n>(
449 &'n self,
450 node_id: &'a Uuid,
451 safe: bool,
452 only_root: bool,
453 root_ids: Option<&'a BTreeSet<Uuid>>,
454 height: Option<usize>,
455 ) -> impl Iterator<Item = Result<&'n Node, NodeStoreError>>
456 where
457 Self: Sized,
458 {
459 self.ascendant_ids(node_id, safe, only_root, root_ids, height)
460 .filter_map(|r| match r {
461 Ok(id) => self.get_node(id).map(Ok),
462 Err(e) => Some(Err(e)),
463 })
464 }
465
466 fn node_depth(
471 &self,
472 node_id: &Uuid,
473 safe: bool,
474 root_ids: Option<&BTreeSet<Uuid>>,
475 height: Option<usize>,
476 ) -> Result<usize, NodeStoreError>
477 where
478 Self: Sized,
479 {
480 self.ascendant_ids(node_id, safe, false, root_ids, height)
481 .try_fold(0usize, |acc, id| id.map(|_| acc + 1))
482 }
483
484 fn descendant_ids<'a, 'n>(
490 &'n self,
491 node_id: &'a Uuid,
492 safe: bool,
493 only_leaf: bool,
494 leaf_ids: Option<&'a BTreeSet<Uuid>>,
495 depth: Option<usize>,
496 ) -> impl Iterator<Item = Result<&'n Uuid, NodeStoreError>>
497 where
498 Self: Sized,
499 {
500 DescendantIterator::new(self, node_id, safe, only_leaf, leaf_ids, depth)
501 }
502
503 fn descendant_nodes<'a, 'n>(
509 &'n self,
510 node_id: &'a Uuid,
511 safe: bool,
512 only_leaf: bool,
513 leaf_ids: Option<&'a BTreeSet<Uuid>>,
514 depth: Option<usize>,
515 ) -> impl Iterator<Item = Result<&'n Node, NodeStoreError>>
516 where
517 Self: Sized,
518 {
519 self.descendant_ids(node_id, safe, only_leaf, leaf_ids, depth)
520 .filter_map(|r| match r {
521 Ok(id) => self.get_node(id).map(Ok),
522 Err(e) => Some(Err(e)),
523 })
524 }
525
526 fn node_height(
531 &self,
532 node_id: &Uuid,
533 safe: bool,
534 leaf_ids: Option<&BTreeSet<Uuid>>,
535 depth: Option<usize>,
536 ) -> Result<usize, NodeStoreError>
537 where
538 Self: Sized,
539 {
540 let mut iterator = DescendantIterator::new(self, node_id, safe, true, leaf_ids, depth);
541 for result in iterator.by_ref() {
542 result?;
543 }
544 Ok(iterator.max_level)
545 }
546
547 fn node_width(
552 &self,
553 node_id: &Uuid,
554 safe: bool,
555 leaf_ids: Option<&BTreeSet<Uuid>>,
556 depth: Option<usize>,
557 ) -> Result<usize, NodeStoreError>
558 where
559 Self: Sized,
560 {
561 self.descendant_ids(node_id, safe, true, leaf_ids, depth)
562 .try_fold(0usize, |acc, id| id.map(|_| acc + 1))
563 }
564
565 fn node_aggregate(&self) -> &Aggregate {
567 &self.node_store().aggregate
568 }
569}
570
571pub struct AscendantIterator<'a, 'n, N>
572where
573 N: NodeStore,
574{
575 nodes: &'n N,
578 safe: bool,
580 only_root: bool,
582 root_ids: Option<&'a BTreeSet<Uuid>>,
584 height: Option<usize>,
586
587 node_id: Uuid,
590 seen: BTreeSet<Uuid>,
592 stop: bool,
594 level: usize,
596 error: bool,
598}
599impl<'a, 'n, N> AscendantIterator<'a, 'n, N>
600where
601 N: NodeStore,
602{
603 pub fn new(
604 nodes: &'n N,
605 node_id: &'a Uuid,
606 safe: bool,
607 only_root: bool,
608 root_ids: Option<&'a BTreeSet<Uuid>>,
609 height: Option<usize>,
610 ) -> Self {
611 Self {
612 nodes,
613 safe,
614 only_root,
615 root_ids,
616 height,
617 node_id: *node_id,
618 seen: BTreeSet::default(),
619 stop: false,
620 level: 0,
621 error: false,
622 }
623 }
624}
625impl<'n, N> Iterator for AscendantIterator<'_, 'n, N>
626where
627 N: NodeStore,
628{
629 type Item = Result<&'n Uuid, NodeStoreError>;
630
631 fn next(&mut self) -> Option<Self::Item> {
632 if self.stop || Some(self.level) == self.height || self.error {
633 return None;
634 }
635
636 let parent_id = self.nodes.get_node(&self.node_id)?.parent.as_ref()?;
638
639 if self.safe && !self.seen.insert(*parent_id) {
641 self.error = true;
642 return Some(Err(NodeStoreError::CyclicAscendants { id: self.node_id }));
643 }
644
645 let parent: &'n Node = self.nodes.get_node(parent_id)?;
647
648 self.level += 1;
650
651 if parent.is_root()
653 || self.height.map(|h| h == 1).unwrap_or(false)
654 || self
655 .root_ids
656 .map(|x| x.contains(parent_id))
657 .unwrap_or(false)
658 {
659 self.stop = true;
660 Some(Ok(parent_id))
661 } else {
662 self.node_id = *parent_id;
664
665 if self.only_root {
668 self.next()
669 } else {
670 Some(Ok(parent_id))
671 }
672 }
673 }
674}
675
676pub struct DescendantIterator<'a, 'n, N>
677where
678 N: NodeStore,
679{
680 nodes: &'n N,
683 safe: bool,
685 only_leaf: bool,
687 leaf_ids: Option<&'a BTreeSet<Uuid>>,
689 depth: Option<usize>,
691
692 descendants: Vec<Vec<Uuid>>,
695 seen: BTreeSet<Uuid>,
697 level: usize,
699 max_level: usize,
701 stop: bool,
703}
704impl<'a, 'n, N> DescendantIterator<'a, 'n, N>
705where
706 N: NodeStore,
707{
708 pub fn new(
709 nodes: &'n N,
710 node_id: &'a Uuid,
711 safe: bool,
712 only_leaf: bool,
713 leaf_ids: Option<&'a BTreeSet<Uuid>>,
714 depth: Option<usize>,
715 ) -> Self {
716 let (stop, level, descendants) = if depth.is_none() || depth != Some(0) {
717 let mut descendants = nodes
718 .get_node(node_id)
719 .map(|n| n.children.clone())
720 .unwrap_or_default();
721 if descendants.is_empty() {
722 (true, 0, vec![])
723 } else {
724 descendants.reverse();
725 (false, 1, descendants)
726 }
727 } else {
728 (true, 0, vec![])
729 };
730 Self {
731 nodes,
732 safe,
733 only_leaf,
734 leaf_ids,
735 depth,
736 descendants: vec![descendants],
737 seen: BTreeSet::from([*node_id]),
738 level,
739 max_level: level,
740 stop,
741 }
742 }
743}
744impl<'n, N> Iterator for DescendantIterator<'_, 'n, N>
745where
746 N: NodeStore,
747{
748 type Item = Result<&'n Uuid, NodeStoreError>;
749
750 fn next(&mut self) -> Option<Self::Item> {
751 if self.stop {
752 return None;
753 }
754
755 while self
757 .descendants
758 .last()
759 .map(|ds| ds.is_empty())
760 .unwrap_or_default()
761 {
762 self.descendants.pop();
763 self.level -= 1;
764 }
765 let node_id = self.descendants.last_mut().and_then(|ds| ds.pop())?;
766
767 if self.safe && !self.seen.insert(node_id) {
769 self.stop = true;
770 return Some(Err(NodeStoreError::CyclicDescendants { id: node_id }));
771 }
772 let node = self.nodes.get_node(&node_id)?;
773
774 if node.is_leaf()
776 || self
777 .leaf_ids
778 .map(|ids| ids.contains(&node_id))
779 .unwrap_or(false)
780 || self.depth.map(|d| d == self.level).unwrap_or(false)
781 {
782 Some(Ok(node.id()))
783 } else {
784 if self.depth.is_none() || self.level < self.depth.unwrap_or_default() {
787 let mut children = node.children.clone();
788 children.reverse();
789 self.descendants.push(children);
790 self.level += 1;
791 self.max_level = self.max_level.max(self.level);
792 }
793 if self.only_leaf {
794 self.next()
795 } else {
796 Some(Ok(node.id()))
797 }
798 }
799 }
800}