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 = match self.iter.next() {
419 None => return None,
420 Some(elt) => elt,
421 };
422 let keep = (self.f)(match elt {
423 Element::Node { ref mut weight } => Element::Node { weight },
424 Element::Edge {
425 source,
426 target,
427 ref mut weight,
428 } => Element::Edge {
429 source,
430 target,
431 weight,
432 },
433 });
434 let is_node = if let Element::Node { .. } = elt {
435 true
436 } else {
437 false
438 };
439 if !keep && is_node {
440 self.map.push(self.node_index);
441 }
442 if is_node {
443 self.node_index += 1;
444 }
445 if !keep {
446 continue;
447 }
448
449 match elt {
451 Element::Edge {
452 ref mut source,
453 ref mut target,
454 ..
455 } => {
456 match self.map.binary_search(source) {
464 Ok(_) => continue,
465 Err(i) => *source -= i,
466 }
467 match self.map.binary_search(target) {
468 Ok(_) => continue,
469 Err(i) => *target -= i,
470 }
471 }
472 Element::Node { .. } => {}
473 }
474 return Some(elt);
475 }
476 }
477 fn size_hint(&self) -> (usize, Option<usize>) {
478 let (_, upper) = self.iter.size_hint();
479 (0, upper)
480 }
481}