1#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5
6use crate::graph::IndexType;
7#[cfg(feature = "graphmap")]
8use crate::graphmap::{GraphMap, NodeTrait};
9#[cfg(feature = "stable_graph")]
10use crate::stable_graph::StableGraph;
11use crate::visit::{Data, NodeCount, NodeIndexable, Reversed};
12use crate::EdgeType;
13use crate::Graph;
14
15trait_template! {
16 pub trait DataMap : Data {
18 @section self
19 fn node_weight(self: &Self, id: Self::NodeId) -> Option<&Self::NodeWeight>;
20 fn edge_weight(self: &Self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>;
21}
22}
23
24macro_rules! access0 {
25 ($e:expr) => {
26 $e.0
27 };
28}
29
30DataMap! {delegate_impl []}
31DataMap! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
32DataMap! {delegate_impl [[G], G, Reversed<G>, access0]}
33
34trait_template! {
35 pub trait DataMapMut : DataMap {
37 @section self
38 fn node_weight_mut(self: &mut Self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>;
39 fn edge_weight_mut(self: &mut Self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>;
40}
41}
42
43DataMapMut! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
44DataMapMut! {delegate_impl [[G], G, Reversed<G>, access0]}
45
46pub trait Build: Data + NodeCount {
48 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId;
49 fn add_edge(
52 &mut self,
53 a: Self::NodeId,
54 b: Self::NodeId,
55 weight: Self::EdgeWeight,
56 ) -> Option<Self::EdgeId> {
57 Some(self.update_edge(a, b, weight))
58 }
59 fn update_edge(
62 &mut self,
63 a: Self::NodeId,
64 b: Self::NodeId,
65 weight: Self::EdgeWeight,
66 ) -> Self::EdgeId;
67}
68
69pub trait Create: Build + Default {
71 fn with_capacity(nodes: usize, edges: usize) -> Self;
72}
73
74impl<N, E, Ty, Ix> Data for Graph<N, E, Ty, Ix>
75where
76 Ix: IndexType,
77{
78 type NodeWeight = N;
79 type EdgeWeight = E;
80}
81
82impl<N, E, Ty, Ix> DataMap for Graph<N, E, Ty, Ix>
83where
84 Ty: EdgeType,
85 Ix: IndexType,
86{
87 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
88 self.node_weight(id)
89 }
90 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
91 self.edge_weight(id)
92 }
93}
94
95impl<N, E, Ty, Ix> DataMapMut for Graph<N, E, Ty, Ix>
96where
97 Ty: EdgeType,
98 Ix: IndexType,
99{
100 fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
101 self.node_weight_mut(id)
102 }
103 fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
104 self.edge_weight_mut(id)
105 }
106}
107
108#[cfg(feature = "stable_graph")]
109impl<N, E, Ty, Ix> DataMap for StableGraph<N, E, Ty, Ix>
110where
111 Ty: EdgeType,
112 Ix: IndexType,
113{
114 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
115 self.node_weight(id)
116 }
117 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
118 self.edge_weight(id)
119 }
120}
121
122#[cfg(feature = "stable_graph")]
123impl<N, E, Ty, Ix> DataMapMut for StableGraph<N, E, Ty, Ix>
124where
125 Ty: EdgeType,
126 Ix: IndexType,
127{
128 fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
129 self.node_weight_mut(id)
130 }
131 fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
132 self.edge_weight_mut(id)
133 }
134}
135
136impl<N, E, Ty, Ix> Build for Graph<N, E, Ty, Ix>
137where
138 Ty: EdgeType,
139 Ix: IndexType,
140{
141 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
142 self.add_node(weight)
143 }
144 fn add_edge(
145 &mut self,
146 a: Self::NodeId,
147 b: Self::NodeId,
148 weight: Self::EdgeWeight,
149 ) -> Option<Self::EdgeId> {
150 Some(self.add_edge(a, b, weight))
151 }
152 fn update_edge(
153 &mut self,
154 a: Self::NodeId,
155 b: Self::NodeId,
156 weight: Self::EdgeWeight,
157 ) -> Self::EdgeId {
158 self.update_edge(a, b, weight)
159 }
160}
161
162#[cfg(feature = "stable_graph")]
163impl<N, E, Ty, Ix> Build for StableGraph<N, E, Ty, Ix>
164where
165 Ty: EdgeType,
166 Ix: IndexType,
167{
168 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
169 self.add_node(weight)
170 }
171 fn add_edge(
172 &mut self,
173 a: Self::NodeId,
174 b: Self::NodeId,
175 weight: Self::EdgeWeight,
176 ) -> Option<Self::EdgeId> {
177 Some(self.add_edge(a, b, weight))
178 }
179 fn update_edge(
180 &mut self,
181 a: Self::NodeId,
182 b: Self::NodeId,
183 weight: Self::EdgeWeight,
184 ) -> Self::EdgeId {
185 self.update_edge(a, b, weight)
186 }
187}
188
189#[cfg(feature = "graphmap")]
190impl<N, E, Ty> Build for GraphMap<N, E, Ty>
191where
192 Ty: EdgeType,
193 N: NodeTrait,
194{
195 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
196 self.add_node(weight)
197 }
198 fn add_edge(
199 &mut self,
200 a: Self::NodeId,
201 b: Self::NodeId,
202 weight: Self::EdgeWeight,
203 ) -> Option<Self::EdgeId> {
204 if self.contains_edge(a, b) {
205 None
206 } else {
207 let r = self.add_edge(a, b, weight);
208 debug_assert!(r.is_none());
209 Some((a, b))
210 }
211 }
212 fn update_edge(
213 &mut self,
214 a: Self::NodeId,
215 b: Self::NodeId,
216 weight: Self::EdgeWeight,
217 ) -> Self::EdgeId {
218 self.add_edge(a, b, weight);
219 (a, b)
220 }
221}
222
223impl<N, E, Ty, Ix> Create for Graph<N, E, Ty, Ix>
224where
225 Ty: EdgeType,
226 Ix: IndexType,
227{
228 fn with_capacity(nodes: usize, edges: usize) -> Self {
229 Self::with_capacity(nodes, edges)
230 }
231}
232
233#[cfg(feature = "stable_graph")]
234impl<N, E, Ty, Ix> Create for StableGraph<N, E, Ty, Ix>
235where
236 Ty: EdgeType,
237 Ix: IndexType,
238{
239 fn with_capacity(nodes: usize, edges: usize) -> Self {
240 Self::with_capacity(nodes, edges)
241 }
242}
243
244#[cfg(feature = "graphmap")]
245impl<N, E, Ty> Create for GraphMap<N, E, Ty>
246where
247 Ty: EdgeType,
248 N: NodeTrait,
249{
250 fn with_capacity(nodes: usize, edges: usize) -> Self {
251 Self::with_capacity(nodes, edges)
252 }
253}
254
255#[derive(Clone, Debug, PartialEq, Eq)]
261pub enum Element<N, E> {
262 Node { weight: N },
264 Edge {
266 source: usize,
267 target: usize,
268 weight: E,
269 },
270}
271
272pub trait FromElements: Create {
274 fn from_elements<I>(iterable: I) -> Self
275 where
276 Self: Sized,
277 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
278 {
279 let mut gr = Self::with_capacity(0, 0);
280 let mut map = Vec::new();
282 for element in iterable {
283 match element {
284 Element::Node { weight } => {
285 map.push(gr.add_node(weight));
286 }
287 Element::Edge {
288 source,
289 target,
290 weight,
291 } => {
292 gr.add_edge(map[source], map[target], weight);
293 }
294 }
295 }
296 gr
297 }
298}
299
300fn from_elements_indexable<G, I>(iterable: I) -> G
301where
302 G: Create + NodeIndexable,
303 I: IntoIterator<Item = Element<G::NodeWeight, G::EdgeWeight>>,
304{
305 let mut gr = G::with_capacity(0, 0);
306 let map = |gr: &G, i| gr.from_index(i);
307 for element in iterable {
308 match element {
309 Element::Node { weight } => {
310 gr.add_node(weight);
311 }
312 Element::Edge {
313 source,
314 target,
315 weight,
316 } => {
317 let from = map(&gr, source);
318 let to = map(&gr, target);
319 gr.add_edge(from, to, weight);
320 }
321 }
322 }
323 gr
324}
325
326impl<N, E, Ty, Ix> FromElements for Graph<N, E, Ty, Ix>
327where
328 Ty: EdgeType,
329 Ix: IndexType,
330{
331 fn from_elements<I>(iterable: I) -> Self
332 where
333 Self: Sized,
334 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
335 {
336 from_elements_indexable(iterable)
337 }
338}
339
340#[cfg(feature = "stable_graph")]
341impl<N, E, Ty, Ix> FromElements for StableGraph<N, E, Ty, Ix>
342where
343 Ty: EdgeType,
344 Ix: IndexType,
345{
346 fn from_elements<I>(iterable: I) -> Self
347 where
348 Self: Sized,
349 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
350 {
351 from_elements_indexable(iterable)
352 }
353}
354
355#[cfg(feature = "graphmap")]
356impl<N, E, Ty> FromElements for GraphMap<N, E, Ty>
357where
358 Ty: EdgeType,
359 N: NodeTrait,
360{
361 fn from_elements<I>(iterable: I) -> Self
362 where
363 Self: Sized,
364 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
365 {
366 from_elements_indexable(iterable)
367 }
368}
369
370pub trait ElementIterator<N, E>: Iterator<Item = Element<N, E>> {
372 fn filter_elements<F>(self, f: F) -> FilterElements<Self, F>
382 where
383 Self: Sized,
384 F: FnMut(Element<&mut N, &mut E>) -> bool,
385 {
386 FilterElements {
387 iter: self,
388 node_index: 0,
389 map: Vec::new(),
390 f,
391 }
392 }
393}
394
395impl<N, E, I: ?Sized> ElementIterator<N, E> for I where I: Iterator<Item = Element<N, E>> {}
396
397pub 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}