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