1use std::{collections::HashSet, marker::PhantomData};
4
5use crate::graph::{Graph, edge::Edge};
6
7pub trait Node<'graph> {
8 type Graph: Graph;
9
10 fn new(id: <Self::Graph as Graph>::NodeId, graph: &'graph Self::Graph) -> Self;
11
12 fn id(&self) -> <Self::Graph as Graph>::NodeId;
14
15 fn graph(&self) -> &'graph Self::Graph;
17
18 fn edge_ids(
20 &self,
21 ) -> &'graph HashSet<<Self::Graph as Graph>::EdgeId, <Self::Graph as Graph>::Hasher>;
22
23 fn edge_count(&self) -> usize;
25
26 fn is_leaf(&self) -> bool {
28 self.edge_count() == 0
29 }
30
31 fn edges(&self) -> Iter<'graph, EdgeMode, Self::Graph> {
33 Iter {
34 graph: self.graph(),
35 node: self.id(),
36 iter: self.edge_ids().iter(),
37 _mode: PhantomData,
38 }
39 }
40
41 fn children(&self) -> Iter<'graph, ChildMode, Self::Graph> {
43 Iter {
44 graph: self.graph(),
45 node: self.id(),
46 iter: self.edge_ids().iter(),
47 _mode: PhantomData,
48 }
49 }
50
51 fn parents(&self) -> Iter<'graph, ParentMode, Self::Graph> {
53 Iter {
54 graph: self.graph(),
55 node: self.id(),
56 iter: self.edge_ids().iter(),
57 _mode: PhantomData,
58 }
59 }
60}
61
62pub trait NodeMut<'graph> {
63 type Graph: Graph;
64
65 fn new(id: <Self::Graph as Graph>::NodeId, graph: &'graph mut Self::Graph) -> Self;
66
67 fn id(&self) -> <Self::Graph as Graph>::NodeId;
69
70 fn graph(&mut self) -> &mut Self::Graph;
72
73 fn edge_ids(&self) -> &HashSet<<Self::Graph as Graph>::EdgeId, <Self::Graph as Graph>::Hasher>;
75
76 fn edge_count(&self) -> usize;
78
79 fn add_edge_id(&mut self, edge: <Self::Graph as Graph>::EdgeId);
81
82 fn remove_edge_id(&mut self, edge: <Self::Graph as Graph>::EdgeId);
84
85 fn as_ref<'a>(&'a mut self) -> <Self::Graph as Graph>::Node<'a>
87 where
88 'graph: 'a,
89 {
90 <Self::Graph as Graph>::Node::new(self.id(), &*self.graph())
91 }
92}
93
94pub struct EdgeItem<'graph, G: Graph> {
96 pub(crate) graph: &'graph G,
97 pub(crate) edge: G::EdgeId,
98 pub(crate) node: G::NodeId,
99}
100
101impl<'graph, G: Graph> EdgeItem<'graph, G> {
102 pub fn edge_id(&self) -> G::EdgeId {
104 self.edge
105 }
106
107 pub fn node_id(&self) -> G::NodeId {
109 self.node
110 }
111
112 pub fn node(&self) -> G::Node<'graph> {
114 <G as Graph>::Node::new(self.node, self.graph)
115 }
116
117 pub fn edge(&self) -> G::Edge<'graph> {
119 <G as Graph>::Edge::new(self.edge, self.graph)
120 }
121}
122
123pub struct ChildMode;
125
126pub struct ParentMode;
128
129pub struct EdgeMode;
131
132pub struct Iter<'graph, Mode, G: Graph> {
134 graph: &'graph G,
135 node: G::NodeId,
136 iter: std::collections::hash_set::Iter<'graph, G::EdgeId>,
137 _mode: PhantomData<Mode>,
138}
139
140impl<'graph, G: Graph> Iterator for Iter<'graph, ChildMode, G> {
141 type Item = EdgeItem<'graph, G>;
142
143 fn next(&mut self) -> Option<Self::Item> {
144 for &id in self.iter.by_ref() {
145 let edge = <G as Graph>::Edge::new(id, self.graph);
146
147 if self.node == edge.from_id() {
148 return Some(EdgeItem {
149 graph: self.graph,
150 edge: id,
151 node: edge.to_id(),
152 });
153 }
154 }
155
156 None
157 }
158}
159
160impl<'graph, G: Graph> Iterator for Iter<'graph, ParentMode, G> {
161 type Item = EdgeItem<'graph, G>;
162
163 fn next(&mut self) -> Option<Self::Item> {
164 for id in self.iter.by_ref() {
165 let edge = <G as Graph>::Edge::new(*id, self.graph);
166
167 if self.node == edge.to_id() {
168 return Some(EdgeItem {
169 graph: self.graph,
170 edge: *id,
171 node: edge.from_id(),
172 });
173 }
174 }
175
176 None
177 }
178}
179
180impl<'graph, G: Graph> Iterator for Iter<'graph, EdgeMode, G> {
181 type Item = EdgeItem<'graph, G>;
182
183 fn next(&mut self) -> Option<Self::Item> {
184 self.iter.next().map(|&id| {
185 let edge = <G as Graph>::Edge::new(id, self.graph);
186 let other_node = if self.node == edge.from_id() {
187 edge.to_id()
188 } else {
189 edge.from_id()
190 };
191
192 EdgeItem {
193 graph: self.graph,
194 edge: id,
195 node: other_node,
196 }
197 })
198 }
199}