use crate::RatError;
use std::str::FromStr;
pub struct Endpoint {
url: reqwest::Url,
method: reqwest::Method,
verbose: Option<bool>,
}
impl Endpoint {
fn parse_method(method: &str) -> Result<reqwest::Method, RatError> {
use reqwest::Method;
let method = method.to_lowercase();
let method = match method.as_ref() {
"get" => Method::GET,
"post" => Method::POST,
"put" => Method::PUT,
"patch" => Method::PATCH,
"delete" => Method::DELETE,
"head" => Method::HEAD,
"options" => Method::OPTIONS,
_ => return Err(RatError::InvalidRestMethod(method)),
};
Ok(method)
}
fn parse_url(url: &str) -> Result<reqwest::Url, RatError> {
match reqwest::Url::from_str(url) {
Ok(u) => Ok(u),
Err(e) => Err(RatError::InvalidUrl(e.to_string())),
}
}
pub fn new(url: &str, method: &str, verbose: Option<bool>) -> Result<Self, RatError> {
let method = Self::parse_method(method)?;
let url = Self::parse_url(url)?;
Ok(Self {
url,
method,
verbose,
})
}
pub fn build(self) -> reqwest::blocking::Request {
let req = reqwest::blocking::Request::new(self.method, self.url);
if self.verbose == Some(true) {
log::debug!("{:#?}", req);
}
req
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn endpoint_parsing_works() -> Result<(), RatError> {
let url = "https://google.com";
for m in vec!["get", "post", "put", "delete", "patch", "head", "options"] {
assert!(Endpoint::new(url, m, None).is_ok());
assert!(Endpoint::new(url, m.to_uppercase().as_ref(), None).is_ok());
}
assert_eq!(Endpoint::parse_method("get")?, reqwest::Method::GET);
assert!(matches!(
Endpoint::new(url, "invalid", None),
Err(RatError::InvalidRestMethod(_))
));
assert!(matches!(
Endpoint::new("not-a-valid-url", "get", None),
Err(RatError::InvalidUrl(_))
));
Ok(())
}
}