use http::Method; use std::collections::HashMap; use url::ParseError; use crate::into_url::IntoUrl; use crate::response; // The DEFAULT_USER_AGENT is setted in the build.rs script // and can be overwritten in compiled time static DEFAULT_USER_AGENT: &str = env!("DEFAULT_USER_AGENT"); #[derive(Clone)] pub enum ParameterType { Number(isize), Decimal(f64), Boolean(bool), Text(String), } pub trait RequestBase { fn new<T: IntoUrl>(url: T) -> Result<Self, ParseError> where Self: Sized; fn launch(self) -> response::Response; } #[derive(Debug)] pub struct Request { pub url: url::Url, pub user_agent: String, method: Method, params: Vec<(String, String)>, headers: HashMap<String, String>, } impl RequestBase for Request { fn new<T: IntoUrl>(url: T) -> Result<Request, ParseError> { url.into_url().map(|url_parsed| Request { url: url_parsed, user_agent: DEFAULT_USER_AGENT.to_string(), method: Method::GET, params: Vec::new(), headers: HashMap::new(), }) } fn launch(mut self) -> response::Response { let client = reqwest::blocking::Client::builder() .user_agent(self.user_agent) .build() .unwrap(); // Set GET params for (key, value) in &self.params { self.url.query_pairs_mut().append_pair(key, value); } let resp = (match self.method { Method::GET => client.get(self.url.as_str()), Method::POST => client.post(self.url.as_str()), Method::PUT => client.put(self.url.as_str()), Method::PATCH => client.patch(self.url.as_str()), Method::DELETE => client.delete(self.url.as_str()), _ => unimplemented!(), }) .send() .unwrap(); let status = resp.status(); let text = resp.text().unwrap(); let url = self.url; response::Response { text: text, status_code: status, url: url, } } } impl std::string::ToString for ParameterType { fn to_string(&self) -> String { match self { ParameterType::Number(n) => n.to_string(), ParameterType::Decimal(n) => n.to_string(), ParameterType::Boolean(n) => n.to_string(), ParameterType::Text(t) => t.clone(), } } } impl Request { pub fn method(mut self, method: Method) -> Self { self.method = method; self } pub fn set_user_agent<S: AsRef<str>>(mut self, user_agent: S) -> Self { self.user_agent = user_agent.as_ref().to_string(); self } pub fn add_params<S: AsRef<str>, T: ToString>(mut self, params: Vec<(S, T)>) -> Self { self.params = params .iter() .map(|item| (item.0.as_ref().to_string(), item.1.to_string())) .collect(); self } pub fn add_param<S: AsRef<str>, T: ToString>(&mut self, key: S, value: T) { self.params .push((key.as_ref().to_string(), value.to_string())); } }