dialtone_reqwest 0.1.0

Dialtone HTTP Reqwest Client Library
Documentation
use crate::dt_reqwest_error::DtReqwestError;
use dialtone_common::rest::users::user_login::AuthBody;
use reqwest::{Client, RequestBuilder};
use serde::{Deserialize, Serialize};

#[cfg(not(target_arch = "wasm32"))]
static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SiteConnection {
    pub host_addr: String,
    pub secure: bool,
    pub auth_data: Option<AuthBody>,
    pub host_name: Option<String>,
    pub user_name: Option<String>,
}

pub struct PathArgument<'a> {
    pub path_segment_name: &'a str,
    pub path_segment_value: &'a str,
}

impl SiteConnection {
    #[cfg(not(target_arch = "wasm32"))]
    pub fn new(host_addr: &str) -> SiteConnection {
        SiteConnection {
            host_addr: host_addr.to_string(),
            secure: false,
            auth_data: None,
            host_name: None,
            user_name: None,
        }
    }

    #[cfg(not(target_arch = "wasm32"))]
    pub fn new_site(host_addr: &str, host_name: &str) -> SiteConnection {
        SiteConnection {
            host_addr: host_addr.to_string(),
            secure: false,
            auth_data: None,
            host_name: Some(host_name.to_string()),
            user_name: None,
        }
    }

    #[cfg(not(target_arch = "wasm32"))]
    pub fn new_client(&self) -> Client {
        reqwest::Client::builder()
            .user_agent(APP_USER_AGENT)
            .build()
            .unwrap()
    }

    #[cfg(target_arch = "wasm32")]
    pub fn new(host_addr: &str) -> SiteConnection {
        SiteConnection {
            host_addr: host_addr.to_string(),
            secure: false,
            auth_data: None,
            host_name: None,
            user_name: None,
        }
    }

    #[cfg(target_arch = "wasm32")]
    pub fn new_site(host_addr: &str, host_name: &str) -> SiteConnection {
        SiteConnection {
            host_addr: host_addr.to_string(),
            secure: false,
            auth_data: None,
            host_name: Some(host_name.to_string()),
            user_name: None,
        }
    }

    #[cfg(target_arch = "wasm32")]
    pub fn new_client(&self) -> Client {
        reqwest::Client::builder().build().unwrap()
    }

    pub fn base_url(&self) -> String {
        let scheme = match self.secure {
            true => "https://",
            false => "http://",
        };
        format!("{}{}", scheme, self.host_addr)
    }

    pub fn url(&self, path: &str, args: &[PathArgument]) -> String {
        let mut new_path = path.to_string();
        for arg in args {
            new_path = new_path.replacen(arg.path_segment_name, arg.path_segment_value, 1);
        }
        format!("{}{}", self.base_url(), new_path)
    }

    pub fn host_name(&self) -> &str {
        match &self.host_name {
            None => &self.host_addr,
            Some(host_name) => host_name.as_str(),
        }
    }

    pub fn get(&self, path: &str, args: &[PathArgument]) -> RequestBuilder {
        self.do_method(self.new_client().get(self.url(path, args)))
    }

    pub fn get_with_client(
        &self,
        client: &Client,
        path: &str,
        args: &[PathArgument],
    ) -> RequestBuilder {
        self.do_method(client.get(self.url(path, args)))
    }

    pub fn post(&self, path: &str, args: &[PathArgument]) -> RequestBuilder {
        self.do_method(self.new_client().post(self.url(path, args)))
    }

    pub fn post_with_client(
        &self,
        client: &Client,
        path: &str,
        args: &[PathArgument],
    ) -> RequestBuilder {
        self.do_method(client.post(self.url(path, args)))
    }

    pub fn put(&self, path: &str, args: &[PathArgument]) -> RequestBuilder {
        self.do_method(self.new_client().put(self.url(path, args)))
    }

    pub fn put_with_client(
        &self,
        client: &Client,
        path: &str,
        args: &[PathArgument],
    ) -> RequestBuilder {
        self.do_method(client.put(self.url(path, args)))
    }

    pub fn patch(&self, path: &str, args: &[PathArgument]) -> RequestBuilder {
        self.do_method(self.new_client().patch(self.url(path, args)))
    }

    pub fn patch_with_client(
        &self,
        client: &Client,
        path: &str,
        args: &[PathArgument],
    ) -> RequestBuilder {
        self.do_method(client.patch(self.url(path, args)))
    }

    pub fn delete(&self, path: &str, args: &[PathArgument]) -> RequestBuilder {
        self.do_method(self.new_client().delete(self.url(path, args)))
    }

    pub fn delete_with_client(
        &self,
        client: &Client,
        path: &str,
        args: &[PathArgument],
    ) -> RequestBuilder {
        self.do_method(client.delete(self.url(path, args)))
    }

    pub fn head(&self, path: &str, args: &[PathArgument]) -> RequestBuilder {
        self.do_method(self.new_client().head(self.url(path, args)))
    }

    pub fn head_with_client(
        &self,
        client: &Client,
        path: &str,
        args: &[PathArgument],
    ) -> RequestBuilder {
        self.do_method(client.head(self.url(path, args)))
    }

    pub fn must_be_logged_in(&self) -> Result<(), DtReqwestError> {
        if self.user_name.is_none() {
            Err(DtReqwestError::AuthenticationRequired)
        } else {
            Ok(())
        }
    }

    fn do_method(&self, rb: RequestBuilder) -> RequestBuilder {
        match self.auth_data {
            None => rb,
            Some(_) => rb.bearer_auth(&self.auth_data.as_ref().unwrap().access_token),
        }
    }
}

impl PathArgument<'_> {
    pub fn new<'a>(name: &'a str, value: &'a str) -> PathArgument<'a> {
        PathArgument {
            path_segment_name: name,
            path_segment_value: value,
        }
    }
}