spiral-auth 0.1.12

Spiral credentials: bearer tokens and the providers that obtain them
Documentation
//! The HTTP client that credential providers share.

use async_trait::async_trait;
use reqwest::Response;
#[cfg(test)]
pub(crate) use tests::test_client;

use crate::{CredentialError, CredentialResult};

/// Treats an unsuccessful response as a rejection that carries its status and body.
#[async_trait]
pub(crate) trait Accepted: Sized {
    /// The response if it succeeded, else the status and body it was rejected with.
    async fn accepted(self) -> CredentialResult<Self>;
}

#[async_trait]
impl Accepted for Response {
    async fn accepted(self) -> CredentialResult<Self> {
        let status = self.status();
        if status.is_success() {
            return Ok(self);
        }
        let url = self.url().clone();
        let body = self.text().await?;
        Err(CredentialError::Rejected { url, status, body })
    }
}

#[cfg(test)]
mod tests {
    use reqwest::Client;
    use reqwest::redirect::Policy;
    use reqwest_middleware::ClientWithMiddleware;

    use crate::install_default_crypto_provider;

    #[expect(
        clippy::disallowed_methods,
        reason = "Tests supply their own credential transport"
    )]
    pub(crate) fn test_client() -> ClientWithMiddleware {
        install_default_crypto_provider();
        Client::builder()
            .redirect(Policy::none())
            .build()
            .unwrap()
            .into()
    }
}