use crate::config::{PubsubConnection, PubsubCredentials};
use faucet_core::FaucetError;
use gcloud_auth::credentials::CredentialsFile;
use gcloud_pubsub::client::{Client, ClientConfig};
fn auth_err(context: &str, e: impl std::fmt::Display) -> FaucetError {
FaucetError::Auth(format!("pubsub auth ({context}): {e}"))
}
pub async fn build_client(conn: &PubsubConnection) -> Result<Client, FaucetError> {
if let Some(host) = &conn.emulator_host
&& std::env::var_os("PUBSUB_EMULATOR_HOST").is_none()
{
unsafe {
std::env::set_var("PUBSUB_EMULATOR_HOST", host);
}
}
let mut config = ClientConfig::default();
if let Some(project) = &conn.project_id {
config.project_id = Some(project.clone());
}
if let Some(endpoint) = &conn.endpoint {
config.endpoint = endpoint.clone();
}
let use_auth = conn.effective_emulator_host().is_none()
&& conn.credentials != PubsubCredentials::Anonymous;
let config = if use_auth {
match &conn.credentials {
PubsubCredentials::Anonymous => config, PubsubCredentials::ApplicationDefault => config
.with_auth()
.await
.map_err(|e| auth_err("application default", e))?,
PubsubCredentials::ServiceAccountJsonFile { path } => {
let cf = CredentialsFile::new_from_file(path.clone())
.await
.map_err(|e| auth_err("service-account file", e))?;
config
.with_credentials(cf)
.await
.map_err(|e| auth_err("service-account file", e))?
}
PubsubCredentials::ServiceAccountJsonInline { json } => {
let cf = CredentialsFile::new_from_str(json)
.await
.map_err(|e| auth_err("inline service-account key", e))?;
config
.with_credentials(cf)
.await
.map_err(|e| auth_err("inline service-account key", e))?
}
}
} else {
config
};
Client::new(config)
.await
.map_err(|e| FaucetError::Source(format!("pubsub: client build failed: {e}")))
}