1use crate::graph::IndexType;
4#[cfg(feature = "graphmap")]
5use crate::graphmap::{GraphMap, NodeTrait};
6#[cfg(feature = "stable_graph")]
7use crate::stable_graph::StableGraph;
8use crate::visit::{Data, NodeCount, NodeIndexable, Reversed};
9use crate::EdgeType;
10use crate::Graph;
11
12trait_template! {
13 #[allow(clippy::needless_arbitrary_self_type)]
15pub trait DataMap : Data {
16 @section self
17 fn node_weight(self: &Self, id: Self::NodeId) -> Option<&Self::NodeWeight>;
18 fn edge_weight(self: &Self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>;
19}
20}
21
22macro_rules! access0 {
23 ($e:expr) => {
24 $e.0
25 };
26}
27
28DataMap! {delegate_impl []}
29DataMap! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
30DataMap! {delegate_impl [[G], G, Reversed<G>, access0]}
31
32trait_template! {
33 #[allow(clippy::needless_arbitrary_self_type)]
35pub trait DataMapMut : DataMap {
36 @section self
37 fn node_weight_mut(self: &mut Self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>;
38 fn edge_weight_mut(self: &mut Self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>;
39}
40}
41
42DataMapMut! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
43DataMapMut! {delegate_impl [[G], G, Reversed<G>, access0]}
44
45pub trait Build: Data + NodeCount {
47 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId;
48 fn add_edge(
51 &mut self,
52 a: Self::NodeId,
53 b: Self::NodeId,
54 weight: Self::EdgeWeight,
55 ) -> Option<Self::EdgeId> {
56 Some(self.update_edge(a, b, weight))
57 }
58 fn update_edge(
61 &mut self,
62 a: Self::NodeId,
63 b: Self::NodeId,
64 weight: Self::EdgeWeight,
65 ) -> Self::EdgeId;
66}
67
68pub trait Create: Build + Default {
70 fn with_capacity(nodes: usize, edges: usize) -> Self;
71}
72
73impl<N, E, Ty, Ix> Data for Graph<N, E, Ty, Ix>
74where
75 Ix: IndexType,
76{
77 type NodeWeight = N;
78 type EdgeWeight = E;
79}
80
81impl<N, E, Ty, Ix> DataMap for Graph<N, E, Ty, Ix>
82where
83 Ty: EdgeType,
84 Ix: IndexType,
85{
86 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
87 self.node_weight(id)
88 }
89 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
90 self.edge_weight(id)
91 }
92}
93
94impl<N, E, Ty, Ix> DataMapMut for Graph<N, E, Ty, Ix>
95where
96 Ty: EdgeType,
97 Ix: IndexType,
98{
99 fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
100 self.node_weight_mut(id)
101 }
102 fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
103 self.edge_weight_mut(id)
104 }
105}
106
107#[cfg(feature = "stable_graph")]
108impl<N, E, Ty, Ix> DataMap for StableGraph<N, E, Ty, Ix>
109where
110 Ty: EdgeType,
111 Ix: IndexType,
112{
113 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
114 self.node_weight(id)
115 }
116 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
117 self.edge_weight(id)
118 }
119}
120
121#[cfg(feature = "stable_graph")]
122impl<N, E, Ty, Ix> DataMapMut for StableGraph<N, E, Ty, Ix>
123where
124 Ty: EdgeType,
125 Ix: IndexType,
126{
127 fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
128 self.node_weight_mut(id)
129 }
130 fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
131 self.edge_weight_mut(id)
132 }
133}
134
135impl<N, E, Ty, Ix> Build for Graph<N, E, Ty, Ix>
136where
137 Ty: EdgeType,
138 Ix: IndexType,
139{
140 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
141 self.add_node(weight)
142 }
143 fn add_edge(
144 &mut self,
145 a: Self::NodeId,
146 b: Self::NodeId,
147 weight: Self::EdgeWeight,
148 ) -> Option<Self::EdgeId> {
149 Some(self.add_edge(a, b, weight))
150 }
151 fn update_edge(
152 &mut self,
153 a: Self::NodeId,
154 b: Self::NodeId,
155 weight: Self::EdgeWeight,
156 ) -> Self::EdgeId {
157 self.update_edge(a, b, weight)
158 }
159}
160
161#[cfg(feature = "stable_graph")]
162impl<N, E, Ty, Ix> Build for StableGraph<N, E, Ty, Ix>
163where
164 Ty: EdgeType,
165 Ix: IndexType,
166{
167 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
168 self.add_node(weight)
169 }
170 fn add_edge(
171 &mut self,
172 a: Self::NodeId,
173 b: Self::NodeId,
174 weight: Self::EdgeWeight,
175 ) -> Option<Self::EdgeId> {
176 Some(self.add_edge(a, b, weight))
177 }
178 fn update_edge(
179 &mut self,
180 a: Self::NodeId,
181 b: Self::NodeId,
182 weight: Self::EdgeWeight,
183 ) -> Self::EdgeId {
184 self.update_edge(a, b, weight)
185 }
186}
187
188#[cfg(feature = "graphmap")]
189impl<N, E, Ty> Build for GraphMap<N, E, Ty>
190where
191 Ty: EdgeType,
192 N: NodeTrait,
193{
194 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
195 self.add_node(weight)
196 }
197 fn add_edge(
198 &mut self,
199 a: Self::NodeId,
200 b: Self::NodeId,
201 weight: Self::EdgeWeight,
202 ) -> Option<Self::EdgeId> {
203 if self.contains_edge(a, b) {
204 None
205 } else {
206 let r = self.add_edge(a, b, weight);
207 debug_assert!(r.is_none());
208 Some((a, b))
209 }
210 }
211 fn update_edge(
212 &mut self,
213 a: Self::NodeId,
214 b: Self::NodeId,
215 weight: Self::EdgeWeight,
216 ) -> Self::EdgeId {
217 self.add_edge(a, b, weight);
218 (a, b)
219 }
220}
221
222impl<N, E, Ty, Ix> Create for Graph<N, E, Ty, Ix>
223where
224 Ty: EdgeType,
225 Ix: IndexType,
226{
227 fn with_capacity(nodes: usize, edges: usize) -> Self {
228 Self::with_capacity(nodes, edges)
229 }
230}
231
232#[cfg(feature = "stable_graph")]
233impl<N, E, Ty, Ix> Create for StableGraph<N, E, Ty, Ix>
234where
235 Ty: EdgeType,
236 Ix: IndexType,
237{
238 fn with_capacity(nodes: usize, edges: usize) -> Self {
239 Self::with_capacity(nodes, edges)
240 }
241}
242
243#[cfg(feature = "graphmap")]
244impl<N, E, Ty> Create for GraphMap<N, E, Ty>
245where
246 Ty: EdgeType,
247 N: NodeTrait,
248{
249 fn with_capacity(nodes: usize, edges: usize) -> Self {
250 Self::with_capacity(nodes, edges)
251 }
252}
253
254#[derive(Clone, Debug, PartialEq, Eq)]
260pub enum Element<N, E> {
261 Node { weight: N },
263 Edge {
265 source: usize,
266 target: usize,
267 weight: E,
268 },
269}
270
271pub trait FromElements: Create {
273 fn from_elements<I>(iterable: I) -> Self
274 where
275 Self: Sized,
276 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
277 {
278 let mut gr = Self::with_capacity(0, 0);
279 let mut map = Vec::new();
281 for element in iterable {
282 match element {
283 Element::Node { weight } => {
284 map.push(gr.add_node(weight));
285 }
286 Element::Edge {
287 source,
288 target,
289 weight,
290 } => {
291 gr.add_edge(map[source], map[target], weight);
292 }
293 }
294 }
295 gr
296 }
297}
298
299fn from_elements_indexable<G, I>(iterable: I) -> G
300where
301 G: Create + NodeIndexable,
302 I: IntoIterator<Item = Element<G::NodeWeight, G::EdgeWeight>>,
303{
304 let mut gr = G::with_capacity(0, 0);
305 let map = |gr: &G, i| gr.from_index(i);
306 for element in iterable {
307 match element {
308 Element::Node { weight } => {
309 gr.add_node(weight);
310 }
311 Element::Edge {
312 source,
313 target,
314 weight,
315 } => {
316 let from = map(&gr, source);
317 let to = map(&gr, target);
318 gr.add_edge(from, to, weight);
319 }
320 }
321 }
322 gr
323}
324
325impl<N, E, Ty, Ix> FromElements for Graph<N, E, Ty, Ix>
326where
327 Ty: EdgeType,
328 Ix: IndexType,
329{
330 fn from_elements<I>(iterable: I) -> Self
331 where
332 Self: Sized,
333 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
334 {
335 from_elements_indexable(iterable)
336 }
337}
338
339#[cfg(feature = "stable_graph")]
340impl<N, E, Ty, Ix> FromElements for StableGraph<N, E, Ty, Ix>
341where
342 Ty: EdgeType,
343 Ix: IndexType,
344{
345 fn from_elements<I>(iterable: I) -> Self
346 where
347 Self: Sized,
348 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
349 {
350 from_elements_indexable(iterable)
351 }
352}
353
354#[cfg(feature = "graphmap")]
355impl<N, E, Ty> FromElements for GraphMap<N, E, Ty>
356where
357 Ty: EdgeType,
358 N: NodeTrait,
359{
360 fn from_elements<I>(iterable: I) -> Self
361 where
362 Self: Sized,
363 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
364 {
365 from_elements_indexable(iterable)
366 }
367}
368
369pub trait ElementIterator<N, E>: Iterator<Item = Element<N, E>> {
371 fn filter_elements<F>(self, f: F) -> FilterElements<Self, F>
381 where
382 Self: Sized,
383 F: FnMut(Element<&mut N, &mut E>) -> bool,
384 {
385 FilterElements {
386 iter: self,
387 node_index: 0,
388 map: Vec::new(),
389 f,
390 }
391 }
392}
393
394impl<N, E, I: ?Sized> ElementIterator<N, E> for I where I: Iterator<Item = Element<N, E>> {}
395
396#[derive(Debug, Clone)]
402pub struct FilterElements<I, F> {
403 iter: I,
404 node_index: usize,
405 map: Vec<usize>,
406 f: F,
407}
408
409impl<I, F, N, E> Iterator for FilterElements<I, F>
410where
411 I: Iterator<Item = Element<N, E>>,
412 F: FnMut(Element<&mut N, &mut E>) -> bool,
413{
414 type Item = Element<N, E>;
415
416 fn next(&mut self) -> Option<Self::Item> {
417 loop {
418 let mut elt = self.iter.next()?;
419 let keep = (self.f)(match elt {
420 Element::Node { ref mut weight } => Element::Node { weight },
421 Element::Edge {
422 source,
423 target,
424 ref mut weight,
425 } => Element::Edge {
426 source,
427 target,
428 weight,
429 },
430 });
431 let is_node = if let Element::Node { .. } = elt {
432 true
433 } else {
434 false
435 };
436 if !keep && is_node {
437 self.map.push(self.node_index);
438 }
439 if is_node {
440 self.node_index += 1;
441 }
442 if !keep {
443 continue;
444 }
445
446 match elt {
448 Element::Edge {
449 ref mut source,
450 ref mut target,
451 ..
452 } => {
453 match self.map.binary_search(source) {
461 Ok(_) => continue,
462 Err(i) => *source -= i,
463 }
464 match self.map.binary_search(target) {
465 Ok(_) => continue,
466 Err(i) => *target -= i,
467 }
468 }
469 Element::Node { .. } => {}
470 }
471 return Some(elt);
472 }
473 }
474 fn size_hint(&self) -> (usize, Option<usize>) {
475 let (_, upper) = self.iter.size_hint();
476 (0, upper)
477 }
478}