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 if child.parent.as_ref() != Some(node_id) {
203 self.set_parent(child_id, Some(node_id))?;
204 }
205 }
206 }
207 if let Some(parent_id) = node.parent.as_ref() {
208 if let Some(parent) = self.get_node(parent_id) {
209 if !parent.children.contains(node_id) {
210 self.set_parent(node_id, Some(parent_id))?;
211 }
212 }
213 }
214 }
215 for node in nodes.iter() {
217 self.check_node(self.get_node_err(node.id())?)?;
218 }
219 }
220 Ok(replaced)
221 }
222
223 fn check_node(&self, node: &Node) -> Result<(), NodeStoreError>
226 where
227 Self: Sized,
228 {
229 if let Some(parent_id) = &node.parent {
230 if !self.has_node(parent_id) {
231 return NodeNotInStoreSnafu {
232 id: parent_id.to_owned(),
233 }
234 .fail();
235 }
236 }
237 for child_id in node.children.iter() {
238 if !self.has_node(child_id) {
239 return NodeNotInStoreSnafu {
240 id: child_id.to_owned(),
241 }
242 .fail();
243 }
244 }
245 if node.is_bus && node.parent.is_none() {
246 return BusWithoutParentSnafu {
247 id: node.id().to_owned(),
248 }
249 .fail();
250 }
251 self.ascendant_nodes(node.id(), true, true, None, None)
254 .try_fold((), |_, r| r.map(|_| ()))?;
255 self.descendant_nodes(node.id(), true, true, None, None)
256 .try_fold((), |_, r| r.map(|_| ()))?;
257 Ok(())
258 }
259
260 fn get_node(&self, id: &Uuid) -> Option<&Node> {
262 self.node_store().nodes.get(id)
263 }
264 fn get_node_err(&self, id: &Uuid) -> Result<&Node, NodeStoreError> {
266 match self.node_store().nodes.get(id) {
267 Some(node) => Ok(node),
268 None => Err(NodeStoreError::NodeNotInStore { id: id.to_owned() }),
269 }
270 }
271
272 fn get_node_mut(&mut self, node_id: &Uuid) -> Option<&mut Node> {
274 self.node_store_mut().nodes.get_mut(node_id)
275 }
276
277 fn del_node(&mut self, node_id: &Uuid) -> Option<Node> {
279 let store = self.node_store_mut();
280 let deleted = store.nodes.remove(node_id);
281 if let Some(deleted) = deleted.as_ref() {
282 store.aggregate.subtract(deleted.get_meta());
283 store.roots.remove(node_id);
284 store.leafs.remove(node_id);
285 store.depth = None;
286 }
287 deleted
288 }
289
290 fn calculate_node_depth(&self) -> usize
292 where
293 Self: Sized,
294 {
295 self.leaf_ids()
296 .filter_map(|id| self.node_depth(&id, false, None, None).ok())
297 .max()
298 .unwrap_or(0)
299 }
300
301 fn all_node_ids(&self) -> impl Iterator<Item = Uuid> {
303 self.node_store().nodes.keys().copied()
304 }
305
306 fn all_nodes(&self) -> impl Iterator<Item = &Node> {
308 self.node_store().nodes.values()
309 }
310
311 fn root_ids(&self) -> impl Iterator<Item = Uuid> {
313 self.node_store().roots.iter().copied()
314 }
315
316 fn root_nodes(&self) -> impl Iterator<Item = &Node> {
318 self.node_store()
319 .roots
320 .iter()
321 .filter_map(|id| self.get_node(id))
322 }
323
324 fn leaf_ids(&self) -> impl Iterator<Item = Uuid> {
326 self.node_store().leafs.iter().copied()
327 }
328
329 fn leaf_nodes(&self) -> impl Iterator<Item = &Node> {
331 self.node_store()
332 .leafs
333 .iter()
334 .filter_map(|id| self.get_node(id))
335 }
336
337 fn set_parent(
341 &mut self,
342 child_id: &Uuid,
343 parent_id: Option<&Uuid>,
344 ) -> Result<(), NodeStoreError> {
345 if let Some(child) = self.get_node(child_id) {
347 if let Some(current_parent_id) = child.parent {
348 let add_to_leafs = {
349 if let Some(current_parent) = self.get_node_mut(¤t_parent_id) {
350 current_parent.children.retain(|x| x != child_id);
351 current_parent.is_leaf()
352 } else {
353 false
354 }
355 };
356 if add_to_leafs {
357 self.node_store_mut().leafs.insert(current_parent_id);
358 }
359 }
360 } else {
361 return Err(NodeStoreError::NodeNotInStore {
362 id: child_id.to_owned(),
363 });
364 }
365
366 if let Some(parent_id) = parent_id {
368 if self.has_node(parent_id) {
369 if let Some(child) = self.get_node_mut(child_id) {
370 child.parent = Some(parent_id.to_owned());
371 self.node_store_mut().roots.remove(child_id);
372 }
373 if let Some(parent) = self.get_node_mut(parent_id) {
374 if !parent.children.contains(child_id) {
375 parent.children.push(child_id.to_owned())
376 };
377 self.node_store_mut().leafs.remove(parent_id);
378 }
379 } else {
380 return Err(NodeStoreError::NodeNotInStore {
381 id: parent_id.to_owned(),
382 });
383 }
384 } else if let Some(child) = self.get_node_mut(child_id) {
385 child.parent = None;
386 child.is_bus = false;
387 self.node_store_mut().roots.insert(*child_id);
388 }
389 self.node_store_mut().depth = None;
390 Ok(())
391 }
392
393 fn set_bus(&mut self, node_id: &Uuid, is_bus: bool) -> Result<(), NodeStoreError> {
395 if let Some(node) = self.get_node_mut(node_id) {
396 if is_bus && node.parent.is_none() {
397 return Err(NodeStoreError::BusWithoutParent {
398 id: node_id.to_owned(),
399 });
400 }
401 node.is_bus = is_bus;
402 } else {
403 return Err(NodeStoreError::NodeNotInStore {
404 id: node_id.to_owned(),
405 });
406 }
407 Ok(())
408 }
409
410 fn bus_ids(&self, parent_id: &Uuid) -> Result<impl Iterator<Item = Uuid>, NodeStoreError> {
412 Ok(self.bus_nodes(parent_id)?.map(|node| node.id()).copied())
413 }
414
415 fn bus_nodes(&self, parent_id: &Uuid) -> Result<impl Iterator<Item = &Node>, NodeStoreError> {
417 self.get_node_err(parent_id).map(|parent| {
418 parent.children.iter().filter_map(|id| {
419 let node = self.get_node(id)?;
420 if node.is_bus { Some(node) } else { None }
421 })
422 })
423 }
424
425 fn ascendant_ids<'a, 'n>(
431 &'n self,
432 node_id: &'a Uuid,
433 safe: bool,
434 only_root: bool,
435 root_ids: Option<&'a BTreeSet<Uuid>>,
436 height: Option<usize>,
437 ) -> impl Iterator<Item = Result<&'n Uuid, NodeStoreError>>
438 where
439 Self: Sized,
440 {
441 AscendantIterator::new(self, node_id, safe, only_root, root_ids, height)
442 }
443
444 fn ascendant_nodes<'a, 'n>(
450 &'n self,
451 node_id: &'a Uuid,
452 safe: bool,
453 only_root: bool,
454 root_ids: Option<&'a BTreeSet<Uuid>>,
455 height: Option<usize>,
456 ) -> impl Iterator<Item = Result<&'n Node, NodeStoreError>>
457 where
458 Self: Sized,
459 {
460 self.ascendant_ids(node_id, safe, only_root, root_ids, height)
461 .filter_map(|r| match r {
462 Ok(id) => self.get_node(id).map(Ok),
463 Err(e) => Some(Err(e)),
464 })
465 }
466
467 fn node_depth(
472 &self,
473 node_id: &Uuid,
474 safe: bool,
475 root_ids: Option<&BTreeSet<Uuid>>,
476 height: Option<usize>,
477 ) -> Result<usize, NodeStoreError>
478 where
479 Self: Sized,
480 {
481 self.ascendant_ids(node_id, safe, false, root_ids, height)
482 .try_fold(0usize, |acc, id| id.map(|_| acc + 1))
483 }
484
485 fn descendant_ids<'a, 'n>(
491 &'n self,
492 node_id: &'a Uuid,
493 safe: bool,
494 only_leaf: bool,
495 leaf_ids: Option<&'a BTreeSet<Uuid>>,
496 depth: Option<usize>,
497 ) -> impl Iterator<Item = Result<&'n Uuid, NodeStoreError>>
498 where
499 Self: Sized,
500 {
501 DescendantIterator::new(self, node_id, safe, only_leaf, leaf_ids, depth)
502 }
503
504 fn descendant_nodes<'a, 'n>(
510 &'n self,
511 node_id: &'a Uuid,
512 safe: bool,
513 only_leaf: bool,
514 leaf_ids: Option<&'a BTreeSet<Uuid>>,
515 depth: Option<usize>,
516 ) -> impl Iterator<Item = Result<&'n Node, NodeStoreError>>
517 where
518 Self: Sized,
519 {
520 self.descendant_ids(node_id, safe, only_leaf, leaf_ids, depth)
521 .filter_map(|r| match r {
522 Ok(id) => self.get_node(id).map(Ok),
523 Err(e) => Some(Err(e)),
524 })
525 }
526
527 fn node_height(
532 &self,
533 node_id: &Uuid,
534 safe: bool,
535 leaf_ids: Option<&BTreeSet<Uuid>>,
536 depth: Option<usize>,
537 ) -> Result<usize, NodeStoreError>
538 where
539 Self: Sized,
540 {
541 let mut iterator = DescendantIterator::new(self, node_id, safe, true, leaf_ids, depth);
542 for result in iterator.by_ref() {
543 result?;
544 }
545 Ok(iterator.max_level)
546 }
547
548 fn node_width(
553 &self,
554 node_id: &Uuid,
555 safe: bool,
556 leaf_ids: Option<&BTreeSet<Uuid>>,
557 depth: Option<usize>,
558 ) -> Result<usize, NodeStoreError>
559 where
560 Self: Sized,
561 {
562 self.descendant_ids(node_id, safe, true, leaf_ids, depth)
563 .try_fold(0usize, |acc, id| id.map(|_| acc + 1))
564 }
565
566 fn node_aggregate(&self) -> &Aggregate {
568 &self.node_store().aggregate
569 }
570}
571
572pub struct AscendantIterator<'a, 'n, N>
573where
574 N: NodeStore,
575{
576 nodes: &'n N,
579 safe: bool,
581 only_root: bool,
583 root_ids: Option<&'a BTreeSet<Uuid>>,
585 height: Option<usize>,
587
588 node_id: Uuid,
591 seen: BTreeSet<Uuid>,
593 stop: bool,
595 level: usize,
597 error: bool,
599}
600impl<'a, 'n, N> AscendantIterator<'a, 'n, N>
601where
602 N: NodeStore,
603{
604 pub fn new(
605 nodes: &'n N,
606 node_id: &'a Uuid,
607 safe: bool,
608 only_root: bool,
609 root_ids: Option<&'a BTreeSet<Uuid>>,
610 height: Option<usize>,
611 ) -> Self {
612 Self {
613 nodes,
614 safe,
615 only_root,
616 root_ids,
617 height,
618 node_id: *node_id,
619 seen: BTreeSet::default(),
620 stop: false,
621 level: 0,
622 error: false,
623 }
624 }
625}
626impl<'n, N> Iterator for AscendantIterator<'_, 'n, N>
627where
628 N: NodeStore,
629{
630 type Item = Result<&'n Uuid, NodeStoreError>;
631
632 fn next(&mut self) -> Option<Self::Item> {
633 if self.stop || Some(self.level) == self.height || self.error {
634 return None;
635 }
636
637 let parent_id = self.nodes.get_node(&self.node_id)?.parent.as_ref()?;
639
640 if self.safe && !self.seen.insert(*parent_id) {
642 self.error = true;
643 return Some(Err(NodeStoreError::CyclicAscendants { id: self.node_id }));
644 }
645
646 let parent: &'n Node = self.nodes.get_node(parent_id)?;
648
649 self.level += 1;
651
652 if parent.is_root()
654 || self.height.map(|h| h == 1).unwrap_or(false)
655 || self
656 .root_ids
657 .map(|x| x.contains(parent_id))
658 .unwrap_or(false)
659 {
660 self.stop = true;
661 Some(Ok(parent_id))
662 } else {
663 self.node_id = *parent_id;
665
666 if self.only_root {
669 self.next()
670 } else {
671 Some(Ok(parent_id))
672 }
673 }
674 }
675}
676
677pub struct DescendantIterator<'a, 'n, N>
678where
679 N: NodeStore,
680{
681 nodes: &'n N,
684 safe: bool,
686 only_leaf: bool,
688 leaf_ids: Option<&'a BTreeSet<Uuid>>,
690 depth: Option<usize>,
692
693 descendants: Vec<Vec<Uuid>>,
696 seen: BTreeSet<Uuid>,
698 level: usize,
700 max_level: usize,
702 stop: bool,
704}
705impl<'a, 'n, N> DescendantIterator<'a, 'n, N>
706where
707 N: NodeStore,
708{
709 pub fn new(
710 nodes: &'n N,
711 node_id: &'a Uuid,
712 safe: bool,
713 only_leaf: bool,
714 leaf_ids: Option<&'a BTreeSet<Uuid>>,
715 depth: Option<usize>,
716 ) -> Self {
717 let (stop, level, descendants) = if depth.is_none() || depth != Some(0) {
718 let mut descendants = nodes
719 .get_node(node_id)
720 .map(|n| n.children.clone())
721 .unwrap_or_default();
722 if descendants.is_empty() {
723 (true, 0, vec![])
724 } else {
725 descendants.reverse();
726 (false, 1, descendants)
727 }
728 } else {
729 (true, 0, vec![])
730 };
731 Self {
732 nodes,
733 safe,
734 only_leaf,
735 leaf_ids,
736 depth,
737 descendants: vec![descendants],
738 seen: BTreeSet::from([*node_id]),
739 level,
740 max_level: level,
741 stop,
742 }
743 }
744}
745impl<'n, N> Iterator for DescendantIterator<'_, 'n, N>
746where
747 N: NodeStore,
748{
749 type Item = Result<&'n Uuid, NodeStoreError>;
750
751 fn next(&mut self) -> Option<Self::Item> {
752 if self.stop {
753 return None;
754 }
755
756 while self
758 .descendants
759 .last()
760 .map(|ds| ds.is_empty())
761 .unwrap_or_default()
762 {
763 self.descendants.pop();
764 self.level -= 1;
765 }
766 let node_id = self.descendants.last_mut().and_then(|ds| ds.pop())?;
767
768 if self.safe && !self.seen.insert(node_id) {
770 self.stop = true;
771 return Some(Err(NodeStoreError::CyclicDescendants { id: node_id }));
772 }
773 let node = self.nodes.get_node(&node_id)?;
774
775 if node.is_leaf()
777 || self
778 .leaf_ids
779 .map(|ids| ids.contains(&node_id))
780 .unwrap_or(false)
781 || self.depth.map(|d| d == self.level).unwrap_or(false)
782 {
783 Some(Ok(node.id()))
784 } else {
785 if self.depth.is_none() || self.level < self.depth.unwrap_or_default() {
788 let mut children = node.children.clone();
789 children.reverse();
790 self.descendants.push(children);
791 self.level += 1;
792 self.max_level = self.max_level.max(self.level);
793 }
794 if self.only_leaf {
795 self.next()
796 } else {
797 Some(Ok(node.id()))
798 }
799 }
800 }
801}