gt_graph_path/
graph_path.rs1use gt_graph::{Graph, Node};
2use std::fmt::{Debug, Error, Formatter};
3use std::ops::{Deref, DerefMut};
4
5#[derive(Clone)]
6pub struct GraphPath<'a> {
7 graph: &'a dyn Graph,
8 path: Vec<Node>,
9}
10
11impl<'a> PartialEq for GraphPath<'a> {
12 fn eq(&self, other: &Self) -> bool {
13 self.path == other.path
14 }
15}
16
17impl<'a> GraphPath<'a> {
18 #[inline(always)]
19 pub fn new(graph: &'a dyn Graph) -> Self {
20 Self {
21 graph,
22 path: Vec::new(),
23 }
24 }
25
26 #[inline(always)]
27 pub fn new_with_initial_size(graph: &'a dyn Graph, size: usize) -> Self {
28 Self {
29 graph,
30 path: Vec::with_capacity(size),
31 }
32 }
33
34 pub fn from_vec(graph: &'a dyn Graph, src: Vec<Node>) -> Self {
35 Self { graph, path: src }
36 }
37
38 #[inline(always)]
39 pub fn push_validate(&mut self, n: Node) -> Result<(), String> {
40 if self.path.last().is_none()
41 || (1..=self.graph.dimension())
42 .any(|n| self.graph.phi(n, *self.path.last().unwrap()) == n)
43 {
44 self.path.push(n);
45 Ok(())
46 } else {
47 Err("Invalid Path".into())
48 }
49 }
50
51 pub fn is_valid(&self) -> bool {
52 (0..self.path.len() - 1).all(|i| {
53 (1..=self.graph.dimension())
54 .any(|n| self.graph.phi(n, self.path[i]) == self.path[i + 1])
55 })
56 }
57}
58
59impl<'a> Deref for GraphPath<'a> {
60 type Target = Vec<Node>;
61
62 fn deref(&self) -> &Self::Target {
63 &self.path
64 }
65}
66
67impl<'a> DerefMut for GraphPath<'a> {
68 fn deref_mut(&mut self) -> &mut Self::Target {
69 &mut self.path
70 }
71}
72
73impl<'a> Debug for GraphPath<'a> {
74 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
75 let mut s = String::new();
76 if !self.path.is_empty() {
77 s.push_str(&format!(
78 "{:0dim$b}",
79 self.path[0],
80 dim = self.graph.dimension() as usize
81 ));
82 for p in self.path.iter().skip(1) {
83 s.push_str(&format!(
84 " -> {:0dim$b}",
85 p,
86 dim = self.graph.dimension() as usize
87 ));
88 }
89 }
90 write!(f, "NodePath {{ {} }}", s)
91 }
92}
93
94pub trait PathsExt {
95 fn contains_node(&self, n: &Node) -> bool;
96}
97
98impl<'a> PathsExt for Vec<GraphPath<'a>> {
99 fn contains_node(&self, n: &Node) -> bool {
100 self.iter().any(|path| path.contains(n))
101 }
102}