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
81
82
use reqwest::{Response, Client, ClientBuilder, Request};
use types::{
    auth::{BasicAuth, BearerAuth},
    data::{Body, Json},
    multipart::{Headers, FormData, QueryString},
    proxy::Proxy,
    redirect::RedirectPolicy,
    timeout::Timeout,
    ConfiguresClient,
    ConfiguresBuilder
};
use clap::{ArgMatches};
use error::{ParsingError, ErrorWrapper};
use std::fmt::Display;
use debug::PrettyPrint;

pub mod parser;
pub mod cli;
pub mod types;
pub mod error;
pub mod debug;

#[derive(Debug)]
pub struct RequestParser {
    request: Request,
    client: Client
}

impl RequestParser {
    pub fn new(matches: ArgMatches) -> Result<RequestParser, ErrorWrapper> {
        let client = RequestParser::configure_client(&matches)?;
        let request = RequestParser::configure_request(&client, &matches)?;

        Ok(RequestParser {request, client})
    }

    pub fn configure_client(matches: &ArgMatches) -> Result<Client, ErrorWrapper> {
        let mut client_builder = ClientBuilder::new();
        client_builder = Proxy::build(client_builder, matches)?;
        client_builder = RedirectPolicy::build(client_builder, matches)?;
        Ok(client_builder.build()?)
    }

    pub fn configure_request(client: &Client, matches: &ArgMatches) -> Result<Request, ErrorWrapper> {
        let url = match matches.value_of("url") {
            Some(url) => url,
            None => return Err(ParsingError::new("no url provided").into())
        };
        let mut req_builder = match matches.value_of("method") {
            Some("get") => client.get(url),
            Some("post") => client.post(url),
            Some("put") => client.put(url),
            Some("head") => client.head(url),
            Some("patch") => client.patch(url),
            Some("delete") => client.delete(url),
            Some(other) => return Err(ParsingError::new(format!("invalid method '{}'", other).as_str()).into()),
            None => return Err(ParsingError::new("No method provided").into())
        };
        req_builder = BasicAuth::build(req_builder, matches)?;
        req_builder = BearerAuth::build(req_builder, matches)?;
        req_builder = Body::build(req_builder, matches)?;
        req_builder = Json::build(req_builder, matches)?;
        req_builder = Headers::build(req_builder, matches)?;
        req_builder = FormData::build(req_builder, matches)?;
        req_builder = QueryString::build(req_builder, matches)?;
        req_builder = Timeout::build(req_builder, matches)?;
        Ok(req_builder.build()?)
    }

    pub async fn send(self) -> Result<Response, String> {
        match self.client.execute(self.request).await {
            Ok(response) => Ok(response),
            Err(err) => Err(format!("{}", err))
        }
    }
}

impl Display for RequestParser {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        write!(f, "{}", self.prettify().unwrap())
    }
}