requests2 0.1.62

simple http client by rust
Documentation
use std::collections::HashMap;

use crate::cache::Store;
use crate::parser::Parser;
use crate::untils::headers::Headers;
use crate::untils::proxies::Proxies;
use crate::value::Value;
use reqwest::blocking::Client;
use select::document::Document;

pub struct Requests<'a, T> {
    pub text: String, // 保存响应的数据,
    pub url: &'a str,
    store: &'a T,
    headers: Headers,
    proxies: Proxies,
}

impl<'a, T> Requests<'a, T>
where
    T: Store,
{
    pub fn new(store: &'a T) -> Requests<T> {
        Requests {
            text: "".to_string(),
            url: "",
            store,
            headers: Headers::None,
            proxies: Proxies::None,
        }
    }

    pub fn parser<F>(&self, parser_call: F, key: &str) -> &T
    where
        F: Fn(Parser) -> Value,
    {
        let document = Document::from(self.text.as_str());
        let mut parser = Parser::new(&document);
        parser.defined_css_processes();
        let result = parser_call(parser);
        self.store.pipes(key, result);
        self.store
    }

    pub fn free_parse<F>(&self, parse_call: F)
    where
        F: Fn(Parser),
    {
        let document = Document::from(self.text.as_str());
        let mut parser = Parser::new(&document);
        parser.defined_css_processes();
        parse_call(parser)
    }

    // pub fn into_parse<F, S>(&self, parse_call: F)
    //     where F: Fn(Parser) -> Box<S> {
    //         let document = Document::from(self.text.as_str());
    //         let parser = Parser::new(&document);
    //         parse_call(parser);
    //     }

    pub fn default_headers(&self) -> Self {
        Self {
            text: self.text.clone(),
            url: self.url,
            store: self.store,
            headers: Headers::Default,
            proxies: self.proxies,
        }
    }

    pub fn connect(&self, url: &'a str) -> Self {
        Self {
            text: self.text.clone(),
            url,
            store: self.store,
            headers: self.headers,
            proxies: self.proxies,
        }
    }

    pub fn headers(&self, headers: &'static str) -> Self {
        Self {
            text: self.text.clone(),
            url: self.url,
            store: self.store,
            headers: Headers::JSON(headers),
            proxies: self.proxies,
        }
    }

    pub fn proxies(&self, proxies: &'static str) -> Self {
        Self {
            text: self.text.clone(),
            url: self.url,
            store: self.store,
            headers: self.headers,
            proxies: Proxies::STR(proxies),
        }
    }

    pub fn send(&self) -> Result<Self, String> {
        // 发送请求
        let text = self._build();

        match text {
            Ok(text) => Ok(Self {
                text,
                url: self.url,
                store: self.store,
                headers: self.headers,
                proxies: self.proxies,
            }),
            Err(err) => Err(err),
        }
    }

    fn _build(&self) -> Result<String, String> {
        let client_builder = Client::builder();

        let client = match self.proxies {
            Proxies::STR(data) => {
                let proxy = reqwest::Proxy::https(data.to_owned()).expect("no connect proxy");
                client_builder.proxy(proxy).build().expect("无法连接到代理")
            }
            Proxies::None => client_builder.build().expect("无法使用http客户端"),
        };

        let mut request_builder = client.get(self.url);

        let res = match self.headers {
            Headers::None => request_builder.send(),
            Headers::Default => {
                // Client::builder().default_headers(Requests::<'a, T>::_contruct_headers(None))
                request_builder.header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36").send()
            }
            Headers::JSON(data) => {
                let object_data: HashMap<String, serde_json::Value> =
                    serde_json::from_str(data).unwrap();

                for (k, v) in object_data {
                    request_builder = request_builder.header(k, v.to_string());
                }
                request_builder.send()
            }
        };

        match res {
            Ok(res) => {
                let data = res.text().unwrap_or_else(|err| {
                    panic!("error url: {}, error: {:?}", self.url, err);
                });
                Ok(data)
            }
            Err(err) => Err(err.to_string()),
        }
    }
}