use std::marker::PhantomData;
use std::sync::Arc;
use ppoppo_sdk_core::token_cache::{
ClientCredentialsSource, TokenCache, TokenCacheConfig,
};
use crate::client::PcsExternalClient;
use crate::error::Error;
use crate::scopes::PcsExternalScopeSet;
use crate::transport::ExternalChannel;
pub struct PcsExternalClientBuilder {
api_url: String,
token_url: String,
client_id: String,
client_secret: String,
cache_config: TokenCacheConfig,
}
impl PcsExternalClientBuilder {
pub fn new(
api_url: impl Into<String>,
token_url: impl Into<String>,
client_id: impl Into<String>,
client_secret: impl Into<String>,
) -> Self {
Self {
api_url: api_url.into(),
token_url: token_url.into(),
client_id: client_id.into(),
client_secret: client_secret.into(),
cache_config: TokenCacheConfig::default(),
}
}
#[must_use]
pub fn from_env() -> Option<Self> {
let api_url = std::env::var("PCS_API_URL").ok()?;
let token_url = std::env::var("PAS_TOKEN_URL").ok()?;
let client_id = std::env::var("PAS_PCS_CLIENT_ID").ok()?;
let client_secret = std::env::var("PAS_PCS_CLIENT_SECRET").ok()?;
Some(Self::new(api_url, token_url, client_id, client_secret))
}
#[must_use]
pub fn with_cache_config(mut self, config: TokenCacheConfig) -> Self {
self.cache_config = config;
self
}
pub async fn build<S: PcsExternalScopeSet>(self) -> Result<PcsExternalClient<S>, Error> {
let channel = ExternalChannel::connect(&self.api_url).await?;
let source = ClientCredentialsSource::new(
self.token_url,
self.client_id,
self.client_secret,
);
let cache = Arc::new(TokenCache::new(Box::new(source), self.cache_config));
Ok(PcsExternalClient {
channel,
cache,
_scope: PhantomData,
})
}
}