1use petgraph::visit::{GraphBase, GraphRef, Walker};
4use std::marker::PhantomData;
5
6#[derive(Clone, Debug)]
8pub struct Recursive<G, F>
9where
10 G: GraphBase,
11{
12 next: G::NodeId,
13 recursive_fn: F,
14 _graph: PhantomData<G>,
15}
16
17impl<G, F> Recursive<G, F>
18where
19 G: GraphBase,
20 F: FnMut(&G, G::NodeId) -> Option<(G::EdgeId, G::NodeId)>,
21{
22 pub fn new(start: G::NodeId, recursive_fn: F) -> Self {
24 Recursive {
25 next: start,
26 recursive_fn: recursive_fn,
27 _graph: PhantomData,
28 }
29 }
30
31 pub fn next(&mut self, g: &G) -> Option<(G::EdgeId, G::NodeId)> {
33 let Recursive {
34 ref mut next,
35 ref mut recursive_fn,
36 ..
37 } = *self;
38 recursive_fn(g, *next).map(|(e, n)| {
39 *next = n;
40 (e, n)
41 })
42 }
43}
44
45impl<'a, G, F> Walker<&'a G> for Recursive<G, F>
46where
47 G: GraphBase,
48 F: FnMut(&G, G::NodeId) -> Option<(G::EdgeId, G::NodeId)>,
49{
50 type Item = (G::EdgeId, G::NodeId);
51 #[inline]
52 fn walk_next(&mut self, g: &G) -> Option<Self::Item> {
53 self.next(g)
54 }
55}
56
57#[derive(Clone, Debug)]
59pub struct Chain<G, A, B> {
60 a: Option<A>,
61 b: B,
62 _graph: PhantomData<G>,
63}
64
65impl<G, A, B> Chain<G, A, B> {
66 pub fn new(a: A, b: B) -> Self {
68 Chain {
69 a: Some(a),
70 b,
71 _graph: PhantomData,
72 }
73 }
74}
75
76impl<'a, G, A, B> Walker<&'a G> for Chain<G, A, B>
77where
78 G: GraphBase,
79 A: Walker<&'a G>,
80 B: Walker<&'a G, Item = A::Item>,
81{
82 type Item = A::Item;
83 #[inline]
84 fn walk_next(&mut self, graph: &'a G) -> Option<Self::Item> {
85 let Chain {
86 ref mut a,
87 ref mut b,
88 ..
89 } = *self;
90 match a.as_mut().and_then(|walker| walker.walk_next(graph)) {
91 Some(step) => Some(step),
92 None => {
93 *a = None;
94 b.walk_next(graph)
95 }
96 }
97 }
98}
99
100#[derive(Clone, Debug)]
104pub struct Filter<G, W, P> {
105 walker: W,
106 predicate: P,
107 _graph: PhantomData<G>,
108}
109
110impl<G, W, P> Filter<G, W, P> {
111 pub fn new(walker: W, predicate: P) -> Self
113 where
114 G: GraphRef,
115 W: Walker<G>,
116 P: FnMut(G, &W::Item) -> bool,
117 {
118 Filter {
119 walker,
120 predicate,
121 _graph: PhantomData,
122 }
123 }
124}
125
126impl<G, W, P> Walker<G> for Filter<G, W, P>
127where
128 G: GraphRef,
129 W: Walker<G>,
130 P: FnMut(G, &W::Item) -> bool,
131{
132 type Item = W::Item;
133 #[inline]
134 fn walk_next(&mut self, graph: G) -> Option<Self::Item> {
135 while let Some(item) = self.walker.walk_next(graph) {
136 if (self.predicate)(graph, &item) {
137 return Some(item);
138 }
139 }
140 None
141 }
142}
143
144#[derive(Clone, Debug)]
146pub struct Peekable<G, W>
147where
148 W: Walker<G>,
149{
150 walker: W,
151 maybe_next: Option<W::Item>,
152 _graph: PhantomData<G>,
153}
154
155impl<G, W> Peekable<G, W>
156where
157 G: GraphRef,
158 W: Walker<G>,
159{
160 pub fn new(walker: W) -> Self {
162 Peekable {
163 walker,
164 maybe_next: None,
165 _graph: PhantomData,
166 }
167 }
168
169 #[inline]
171 pub fn peek(&mut self, graph: G) -> Option<&W::Item> {
172 if self.maybe_next.is_none() {
173 self.maybe_next = self.walker.walk_next(graph);
174 }
175 self.maybe_next.as_ref()
176 }
177}
178
179impl<G, W> Walker<G> for Peekable<G, W>
180where
181 G: GraphRef,
182 W: Walker<G>,
183{
184 type Item = W::Item;
185 #[inline]
186 fn walk_next(&mut self, graph: G) -> Option<Self::Item> {
187 self.maybe_next
188 .take()
189 .or_else(|| self.walker.walk_next(graph))
190 }
191}
192
193#[derive(Clone, Debug)]
197pub struct SkipWhile<G, W, P> {
198 walker: W,
199 maybe_predicate: Option<P>,
200 _graph: PhantomData<G>,
201}
202
203impl<G, W, P> SkipWhile<G, W, P> {
204 pub fn new(walker: W, predicate: P) -> Self
206 where
207 G: GraphRef,
208 W: Walker<G>,
209 P: FnMut(G, &W::Item) -> bool,
210 {
211 SkipWhile {
212 walker,
213 maybe_predicate: Some(predicate),
214 _graph: PhantomData,
215 }
216 }
217}
218
219impl<G, W, P> Walker<G> for SkipWhile<G, W, P>
220where
221 G: GraphRef,
222 W: Walker<G>,
223 P: FnMut(G, &W::Item) -> bool,
224{
225 type Item = W::Item;
226 #[inline]
227 fn walk_next(&mut self, graph: G) -> Option<Self::Item> {
228 match self.maybe_predicate.take() {
229 Some(mut predicate) => {
230 while let Some(item) = self.walker.walk_next(graph) {
231 if !predicate(graph, &item) {
232 return Some(item);
233 }
234 }
235 None
236 }
237 None => self.walker.walk_next(graph),
238 }
239 }
240}
241
242#[derive(Clone, Debug)]
246pub struct TakeWhile<G, W, P> {
247 maybe_walker: Option<W>,
248 predicate: P,
249 _graph: PhantomData<G>,
250}
251
252impl<G, W, P> TakeWhile<G, W, P> {
253 pub fn new(walker: W, predicate: P) -> Self
255 where
256 G: GraphRef,
257 W: Walker<G>,
258 P: FnMut(G, &W::Item) -> bool,
259 {
260 TakeWhile {
261 maybe_walker: Some(walker),
262 predicate,
263 _graph: PhantomData,
264 }
265 }
266}
267
268impl<G, W, P> Walker<G> for TakeWhile<G, W, P>
269where
270 G: GraphRef,
271 W: Walker<G>,
272 P: FnMut(G, &W::Item) -> bool,
273{
274 type Item = W::Item;
275 #[inline]
276 fn walk_next(&mut self, graph: G) -> Option<Self::Item> {
277 let TakeWhile {
278 ref mut maybe_walker,
279 ref mut predicate,
280 ..
281 } = *self;
282 let maybe_next_idx_pair = maybe_walker
283 .as_mut()
284 .and_then(|walker| walker.walk_next(graph));
285 if let Some(item) = maybe_next_idx_pair {
286 if predicate(graph, &item) {
287 return Some(item);
288 } else {
289 *maybe_walker = None;
290 }
291 }
292 None
293 }
294}
295
296#[derive(Clone, Debug)]
298pub struct Skip<G, W> {
299 walker: W,
300 to_skip: usize,
301 _graph: PhantomData<G>,
302}
303
304impl<G, W> Skip<G, W> {
305 pub fn new(walker: W, to_skip: usize) -> Self {
307 Skip {
308 walker,
309 to_skip,
310 _graph: PhantomData,
311 }
312 }
313}
314
315impl<G, W> Walker<G> for Skip<G, W>
316where
317 G: GraphRef,
318 W: Walker<G>,
319{
320 type Item = W::Item;
321 #[inline]
322 fn walk_next(&mut self, graph: G) -> Option<Self::Item> {
323 if self.to_skip > 0 {
324 for _ in 0..self.to_skip {
325 self.walker.walk_next(graph);
326 }
327 self.to_skip = 0;
328 }
329 self.walker.walk_next(graph)
330 }
331}
332
333#[derive(Clone, Debug)]
335pub struct Take<G, W> {
336 walker: W,
337 to_take: usize,
338 _graph: PhantomData<G>,
339}
340
341impl<G, W> Take<G, W> {
342 pub fn new(walker: W, to_take: usize) -> Self {
344 Take {
345 walker,
346 to_take,
347 _graph: PhantomData,
348 }
349 }
350}
351
352impl<G, W> Walker<G> for Take<G, W>
353where
354 G: GraphRef,
355 W: Walker<G>,
356{
357 type Item = W::Item;
358 #[inline]
359 fn walk_next(&mut self, graph: G) -> Option<Self::Item> {
360 if self.to_take > 0 {
361 self.to_take -= 1;
362 self.walker.walk_next(graph)
363 } else {
364 None
365 }
366 }
367}
368
369#[derive(Clone, Debug)]
371pub struct Cycle<G, W> {
372 walker: W,
373 clone: W,
374 _graph: PhantomData<G>,
375}
376
377impl<G, W> Cycle<G, W>
378where
379 W: Clone,
380{
381 pub fn new(walker: W) -> Self {
383 let clone = walker.clone();
384 Cycle {
385 walker,
386 clone,
387 _graph: PhantomData,
388 }
389 }
390}
391
392impl<G, W> Walker<G> for Cycle<G, W>
393where
394 G: GraphRef,
395 W: Walker<G> + Clone,
396{
397 type Item = W::Item;
398 #[inline]
399 fn walk_next(&mut self, graph: G) -> Option<Self::Item> {
400 self.clone.walk_next(graph).or_else(|| {
401 self.clone = self.walker.clone();
402 self.clone.walk_next(graph)
403 })
404 }
405}
406
407#[derive(Clone, Debug)]
411pub struct Inspect<W, F> {
412 walker: W,
413 f: F,
414}
415
416impl<W, F> Inspect<W, F> {
417 pub fn new(walker: W, f: F) -> Self {
419 Inspect { walker, f }
420 }
421}
422
423impl<G, W, F> Walker<G> for Inspect<W, F>
424where
425 G: GraphRef,
426 W: Walker<G>,
427 F: FnMut(G, &W::Item),
428{
429 type Item = W::Item;
430 #[inline]
431 fn walk_next(&mut self, graph: G) -> Option<W::Item> {
432 self.walker.walk_next(graph).map(|item| {
433 (self.f)(graph, &item);
434 item
435 })
436 }
437}