1use crate::traits::{Directed, GraphIter, GraphIterator, Undirected};
59use std::marker::PhantomData;
60
61pub trait Adjacencies<'a> {
64 type Node: Copy + Eq + 'a;
65
66 type Edge: Copy + Eq + 'a;
67
68 type IncidenceIt: GraphIterator<Self, Item = (Self::Edge, Self::Node)>;
69
70 fn neigh_iter(&self, u: Self::Node) -> Self::IncidenceIt;
71
72 fn neighs<'b>(&'b self, u: Self::Node) -> GraphIter<'b, Self, Self::IncidenceIt>
73 where
74 'a: 'b,
75 Self: Sized,
76 {
77 GraphIter(self.neigh_iter(u), self)
78 }
79
80 fn filter<P>(self, predicate: P) -> FilterAdjacencies<Self, P>
81 where
82 Self: Sized,
83 P: for<'r> Fn(&'r (Self::Edge, Self::Node)) -> bool,
84 {
85 FilterAdjacencies(self, predicate)
86 }
87}
88
89pub struct FilterAdjacencies<A, P>(A, P);
90
91#[derive(Clone)]
92pub struct Filtered<I>(I);
93
94impl<A, P, I> GraphIterator<FilterAdjacencies<A, P>> for Filtered<I>
95where
96 I: GraphIterator<A>,
97 P: for<'r> Fn(&'r I::Item) -> bool,
98{
99 type Item = I::Item;
100
101 fn next(&mut self, adj: &FilterAdjacencies<A, P>) -> Option<Self::Item> {
102 while let Some(it) = self.0.next(&adj.0) {
103 if (adj.1)(&it) {
104 return Some(it);
105 }
106 }
107 None
108 }
109}
110
111impl<'a, A, P> Adjacencies<'a> for FilterAdjacencies<A, P>
112where
113 A: Adjacencies<'a>,
114 P: 'a + Clone + for<'r> Fn(&'r (A::Edge, A::Node)) -> bool,
115{
116 type Node = A::Node;
117 type Edge = A::Edge;
118 type IncidenceIt = Filtered<A::IncidenceIt>;
119
120 fn neigh_iter(&self, u: Self::Node) -> Self::IncidenceIt {
121 Filtered(self.0.neigh_iter(u))
122 }
123}
124
125#[derive(Clone)]
126pub struct AdjacenciesWrapIt<I>(I);
127
128impl<I> From<I> for AdjacenciesWrapIt<I> {
129 fn from(it: I) -> Self {
130 AdjacenciesWrapIt(it)
131 }
132}
133
134impl<'g, G, I> GraphIterator<Neighbors<'g, G>> for AdjacenciesWrapIt<I>
135where
136 I: GraphIterator<G>,
137{
138 type Item = I::Item;
139
140 fn next(&mut self, adj: &Neighbors<'g, G>) -> Option<Self::Item> {
141 self.0.next(adj.0)
142 }
143
144 fn size_hint(&self, adj: &Neighbors<'g, G>) -> (usize, Option<usize>) {
145 self.0.size_hint(adj.0)
146 }
147
148 fn count(self, adj: &Neighbors<'g, G>) -> usize {
149 self.0.count(adj.0)
150 }
151}
152
153impl<'g, G, I> GraphIterator<OutEdges<'g, G>> for AdjacenciesWrapIt<I>
154where
155 I: GraphIterator<G>,
156{
157 type Item = I::Item;
158
159 fn next(&mut self, adj: &OutEdges<'g, G>) -> Option<Self::Item> {
160 self.0.next(adj.0)
161 }
162
163 fn size_hint(&self, adj: &OutEdges<'g, G>) -> (usize, Option<usize>) {
164 self.0.size_hint(adj.0)
165 }
166
167 fn count(self, adj: &OutEdges<'g, G>) -> usize {
168 self.0.count(adj.0)
169 }
170}
171
172impl<'g, G, I> GraphIterator<InEdges<'g, G>> for AdjacenciesWrapIt<I>
173where
174 I: GraphIterator<G>,
175{
176 type Item = I::Item;
177
178 fn next(&mut self, adj: &InEdges<'g, G>) -> Option<Self::Item> {
179 self.0.next(adj.0)
180 }
181
182 fn size_hint(&self, adj: &InEdges<'g, G>) -> (usize, Option<usize>) {
183 self.0.size_hint(adj.0)
184 }
185
186 fn count(self, adj: &InEdges<'g, G>) -> usize {
187 self.0.count(adj.0)
188 }
189}
190
191pub struct Neighbors<'g, G>(pub &'g G);
193
194impl<'a, 'g: 'a, G> Adjacencies<'a> for Neighbors<'g, G>
195where
196 G: Undirected,
197{
198 type Node = G::Node<'a>;
199 type Edge = G::Edge<'a>;
200 type IncidenceIt = AdjacenciesWrapIt<G::NeighIt<'a>>;
201
202 fn neigh_iter(&self, u: Self::Node) -> Self::IncidenceIt {
203 self.0.neigh_iter(u).into()
204 }
205}
206
207pub struct OutEdges<'g, G>(pub &'g G);
209
210impl<'a, 'g: 'a, G> Adjacencies<'a> for OutEdges<'g, G>
211where
212 G: Directed,
213{
214 type Node = G::Node<'a>;
215 type Edge = G::Edge<'a>;
216 type IncidenceIt = AdjacenciesWrapIt<G::OutIt<'a>>;
217
218 fn neigh_iter(&self, u: Self::Node) -> Self::IncidenceIt {
219 self.0.out_iter(u).into()
220 }
221}
222
223pub struct InEdges<'g, G>(pub &'g G);
225
226impl<'a, 'g: 'a, G> Adjacencies<'a> for InEdges<'g, G>
227where
228 G: Directed,
229{
230 type Node = G::Node<'a>;
231 type Edge = G::Edge<'a>;
232 type IncidenceIt = AdjacenciesWrapIt<G::InIt<'a>>;
233
234 fn neigh_iter(&self, u: Self::Node) -> Self::IncidenceIt {
235 self.0.in_iter(u).into()
236 }
237}
238
239impl<'a, A, I> GraphIterator<&'a A> for AdjacenciesWrapIt<I>
240where
241 I: GraphIterator<A>,
242{
243 type Item = I::Item;
244
245 fn next(&mut self, adj: &&'a A) -> Option<Self::Item> {
246 self.0.next(*adj)
247 }
248
249 fn size_hint(&self, adj: &&'a A) -> (usize, Option<usize>) {
250 self.0.size_hint(*adj)
251 }
252
253 fn count(self, adj: &&'a A) -> usize {
254 self.0.count(*adj)
255 }
256}
257
258impl<'a, A> Adjacencies<'a> for &'a A
260where
261 A: Adjacencies<'a>,
262{
263 type Node = A::Node;
264 type Edge = A::Edge;
265 type IncidenceIt = AdjacenciesWrapIt<A::IncidenceIt>;
266
267 fn neigh_iter(&self, u: Self::Node) -> Self::IncidenceIt {
268 (*self).neigh_iter(u).into()
269 }
270}
271
272pub struct FnAdj<N, E, Ne, NeIt> {
315 neighsfn: Ne,
316 phantom: PhantomData<(N, E, NeIt)>,
317}
318
319#[derive(Clone)]
320pub struct FnNeighIt<NeIt>
321where
322 NeIt: Clone,
323{
324 it: NeIt,
325}
326
327impl<N, E, Ne, NeIt> GraphIterator<FnAdj<N, E, Ne, NeIt>> for FnNeighIt<NeIt>
328where
329 NeIt: Iterator<Item = (E, N)> + Clone,
330{
331 type Item = (E, N);
332 fn next(&mut self, _g: &FnAdj<N, E, Ne, NeIt>) -> Option<Self::Item> {
333 self.it.next()
334 }
335}
336
337impl<'a, N, E, Ne, NeIt: Clone> Adjacencies<'a> for FnAdj<N, E, Ne, NeIt>
338where
339 N: Copy + Eq + 'a,
340 E: Copy + Eq + 'a,
341 Ne: Fn(N) -> NeIt,
342 NeIt: Iterator<Item = (E, N)> + Clone,
343{
344 type Node = N;
345 type Edge = E;
346 type IncidenceIt = FnNeighIt<NeIt>;
347
348 fn neigh_iter(&self, u: Self::Node) -> Self::IncidenceIt {
349 FnNeighIt { it: (self.neighsfn)(u) }
350 }
351}
352
353impl<'a, N, E, Ne, NeIt: Clone> From<Ne> for FnAdj<N, E, Ne, NeIt>
354where
355 N: Copy + Eq + 'a,
356 E: Copy + Eq + 'a,
357 Ne: Fn(N) -> NeIt,
358 NeIt: Iterator<Item = (E, N)> + Clone,
359{
360 fn from(neighs: Ne) -> Self {
361 FnAdj {
362 neighsfn: neighs,
363 phantom: PhantomData,
364 }
365 }
366}