From 7761e3d56c0977b4bf6ce9984f6c7ea6f97bbf76 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Fri, 14 Feb 2020 05:00:54 +0000 Subject: [PATCH] #1: Add some basic recursion detection --- stork/src/lib.rs | 17 +++++++++++++++-- stork_http/src/lib.rs | 5 +++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/stork/src/lib.rs b/stork/src/lib.rs index 2e76f33..f9c67a9 100644 --- a/stork/src/lib.rs +++ b/stork/src/lib.rs @@ -55,7 +55,7 @@ pub struct Storkable> { parent: Option>>, } -impl<'a, T: Unpin + 'a, C: StorkClient + 'a> Storkable { +impl<'a, T: Unpin + PartialEq + 'a, C: StorkClient + 'a> Storkable { /// Instantiates a new [Storkable] from a T, storking can then /// begin on the given entrypoint using the [Storkable::exec] method. pub fn new(val: T) -> Self { @@ -108,13 +108,26 @@ impl<'a, T: Unpin + 'a, C: StorkClient + 'a> Storkable { try_stream! { let mut children = this.client.run(this.val()); - while let Some(child) = children.next().await { + 'child: while let Some(child) = children.next().await { let child = child.context(StorkError::ClientError)?; if !this.filters.matches(&child) { continue; } + // ensure we're not going to cause a recursive loop by + // checking that the page we're about to yield isn't a + // parent of it + // TODO: should this happen before or after we try to + // TODO: match it against the filters + let mut current_parent = this.parent(); + while let Some(parent) = current_parent { + if parent.value == this.value { + continue 'child; + } + current_parent = parent.parent(); + } + yield Storkable { value: child, client: Arc::clone(&this.client), diff --git a/stork_http/src/lib.rs b/stork_http/src/lib.rs index 30566c2..5de75ef 100644 --- a/stork_http/src/lib.rs +++ b/stork_http/src/lib.rs @@ -105,6 +105,11 @@ impl Link { self.text.clone() } } +impl PartialEq for Link { + fn eq(&self, other: &Self) -> bool { + self.url().as_str() == other.url().as_str() + } +} impl std::str::FromStr for Link { type Err = failure::Error; -- libgit2 1.7.2