rusty-box 0.2.0-alpha

Box.com API wrapper
Documentation
//! Box API authentication
use async_trait::async_trait;

use crate::http_client::{self, Headers};

pub mod access_token;
pub mod auth_ccg;
pub mod auth_developer;

/// Box API errors
#[derive(thiserror::Error, Debug)]
pub enum AuthError {
    /// The request couldn't be completed because there was an error when trying
    /// to do so
    #[error("request: {0}")]
    Client(#[from] reqwest::Error),

    /// The request was made, but the server returned an unsuccessful status
    /// code, such as 404 or 503. In some cases, the response may contain a
    /// custom message from Box.com with more information, which can be
    /// serialized into `Box_model::ApiError`.
    #[error("status code {}", reqwest::Response::status(.0))]
    StatusCode(reqwest::Response),

    #[error("json parse error: {0}")]
    ParseJson(#[from] serde_json::Error),

    #[error("Generic: {message}")]
    Generic { message: String },

    #[error("request: {0}")]
    RequestError(#[from] http_client::reqwest::ReqwestError),
}

/// Trait for authentication methods
#[async_trait]
pub trait Auth<'a> {
    async fn access_token(&mut self) -> Result<String, AuthError>;
    async fn to_json(&mut self) -> Result<String, AuthError>;
    fn base_api_url(&self) -> String;
    fn user_agent(&self) -> String;
    // async fn auth_header(&mut self) -> Result<Headers, AuthError>;
}

impl dyn Auth<'_> {
    pub async fn auth_header(&mut self) -> Result<Headers, AuthError> {
        let mut header = Headers::new();

        let header_name = "Authorization".to_string();
        let header_value = format!("Bearer {}", self.access_token().await?);

        header.insert(header_name, header_value);

        Ok(header)
    }
}

// implement debug
impl std::fmt::Debug for dyn Auth<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Auth").finish()
    }
}