use futures::{pin_mut, StreamExt};
use std::collections::VecDeque;
use stork_http::{HttpStorkable, Link};
#[derive(argh::FromArgs)]
struct Args {
#[argh(option)]
max_depth: Option<usize>,
#[argh(positional)]
url: Link,
}
#[tokio::main]
async fn main() -> failure::Fallible<()> {
let args: Args = argh::from_env();
let url = args.url;
let stream = HttpStorkable::new(url).exec();
pin_mut!(stream);
let mut queue = stream.map(|v| (v, 0)).collect::<VecDeque<_>>().await;
if queue.is_empty() {
panic!("Failed to find any links on the page!");
}
loop {
if queue.is_empty() {
break;
}
let (link, depth) = queue.pop_front().unwrap();
if let Err(e) = link {
eprintln!("Failed to grab a link: {}", e);
continue;
}
let link = link.unwrap();
println!("{}↳ {}", " ".repeat(depth), link.val().url());
if let Some(max_depth) = args.max_depth {
if depth >= max_depth {
continue;
}
}
let children = link.exec();
pin_mut!(children);
while let Some(v) = children.next().await {
queue.push_front((v, depth + 1));
}
}
Ok(())
}