1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#[allow(unused_imports)]
use crate::internal_prelude::*;
use crate::types as rt;

pub trait Expander<JS: rt::JobStateValues, TS: rt::TaskStateValues> {
    fn expand(
        &self,
        ctx: &mut rt::JobCtx<JS, TS>,
        task: &rt::Task,
        status: &rt::HttpStatus,
        document: &select::document::Document,
    );
}

pub struct FollowLinks {
    link_target: rt::LinkTarget
}

impl<JS: rt::JobStateValues, TS: rt::TaskStateValues> Expander<JS, TS> for FollowLinks {
    fn expand(
        &self,
        ctx: &mut rt::JobCtx<JS, TS>,
        task: &rt::Task,
        _status: &rt::HttpStatus,
        document: &select::document::Document,
    ) {
        let links: Vec<rt::Link> = document
            .find(select::predicate::Name("a"))
            .filter_map(|n| rt::Link::new(
                String::from(n.attr("href").unwrap_or("")),
                String::from(n.attr("alt").unwrap_or("")),
                n.text(),
                0,
                self.link_target.clone(),
                &task.link
                ).ok())
            .collect();
        ctx.push_links(links);
    }
}

impl FollowLinks {
    pub fn new(link_target: rt::LinkTarget) -> Self {
        Self {link_target}
    }
}

pub struct LoadImages {
    link_target: rt::LinkTarget
}

impl<JS: rt::JobStateValues, TS: rt::TaskStateValues> Expander<JS, TS> for LoadImages {
    fn expand(
        &self,
        ctx: &mut rt::JobCtx<JS, TS>,
        task: &rt::Task,
        _status: &rt::HttpStatus,
        document: &select::document::Document,
    ) {
        let links: Vec<rt::Link> = document
            .find(select::predicate::Name("img"))
            .filter_map(|n| rt::Link::new(
                String::from(n.attr("src").unwrap_or("")),
                String::from(n.attr("alt").unwrap_or("")),
                n.text(),
                0,
                self.link_target.clone(),
                &task.link
            ).ok())
            .collect();
        ctx.push_links(links);
    }
}

impl LoadImages {
    pub fn new(link_target: rt::LinkTarget) -> Self {
        Self {link_target}
    }
}