use std::env;
use async_trait::async_trait;
use crate::error::{Result, VercelBlobError};
#[async_trait]
pub trait TokenProvider: std::fmt::Debug + Send + Sync {
async fn get_token(&self, operation: &str, pathname: Option<&str>) -> Result<String>;
}
pub(crate) async fn get_token(
provider: Option<&dyn TokenProvider>,
operation: &str,
pathname: Option<&str>,
) -> Result<String> {
if let Some(provider) = provider {
provider.get_token(operation, pathname).await
} else {
env::var("BLOB_READ_WRITE_TOKEN").map_err(|_| VercelBlobError::NotAuthenticated())
}
}
pub struct EnvTokenProvider {
token: String,
}
impl std::fmt::Debug for EnvTokenProvider {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EnvTokenProvider")
.field("token", &"**********")
.finish()
}
}
impl EnvTokenProvider {
pub fn try_new(env_var: &str) -> Result<Self> {
let token = env::var(env_var).map_err(|_| VercelBlobError::NotAuthenticated())?;
Ok(Self { token })
}
}
#[async_trait]
impl TokenProvider for EnvTokenProvider {
async fn get_token(&self, _operation: &str, _pathname: Option<&str>) -> Result<String> {
Ok(self.token.clone())
}
}