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
use super::*;
use reqwest::{
    self,
    header::{self, HeaderMap, HeaderValue},
    Client,
};
const GOOGLE_URL: &str = "https://www.google.com/search?source=hp";

// werid mess half ported from my attempt at using hyper will clean one day
lazy_static! {
    static ref CLIENT: Client = {
        let mut map = HeaderMap::with_capacity(5);
        map.insert(
            header::USER_AGENT,
            HeaderValue::from_static(
                "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
            ),
        );
        map.insert(
            header::ACCEPT,
            HeaderValue::from_static(
                "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            ),
        );
        map.insert(
            header::ACCEPT_ENCODING,
            HeaderValue::from_static("identity"),
        );
        map.insert(
            header::ACCEPT_LANGUAGE,
            HeaderValue::from_static("en-US,en;q=0.5"),
        );
        map.insert(
            header::REFERER,
            HeaderValue::from_static("https://www.google.com/"),
        );
        Client::builder().default_headers(map).build().unwrap()
    };
}

pub fn google(query: &str) -> Result<Vec<GResult>, Box<dyn Error + Send + Sync>> {
    let mut response = CLIENT
        .get(
            &[
                GOOGLE_URL,
                "&q=",
                &percent_encoding::utf8_percent_encode(query, percent_encoding::QUERY_ENCODE_SET)
                    .collect::<Cow<str>>(),
            ]
            .concat(),
        )
        .send()?;
    let result = Html::parse_document(&response.text()?)
        .select(&LINK_SELECT)
        .take(3)
        .map(GResult::try_from)
        .collect::<Result<Vec<GResult>, Box<dyn Error + Send + Sync>>>()?;
    if result.len() != 3 || result.capacity() != 4 {
        return Err("not enough results..".into());
    }
    Ok(result)
}