use crate::client::account::AccountNamespace;
use crate::client::http::NamespaceConfig;
use crate::client::poe::PoeNamespace;
use crate::client::records::RecordsNamespace;
use crate::client::transport::{ClientTransport, ReqwestClientTransport};
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("{0}")]
pub struct InvalidClientConfigError(pub String);
impl InvalidClientConfigError {
pub const CODE: &'static str = "INVALID_CLIENT_CONFIG";
}
#[derive(Debug, Clone, Default)]
pub struct Label309ClientConfig {
pub api_key: Option<String>,
pub base_url: Option<String>,
}
fn resolve_base_url(config: &Label309ClientConfig) -> Result<String, InvalidClientConfigError> {
match &config.base_url {
Some(base_url) if !base_url.is_empty() => Ok(base_url.clone()),
_ => Err(InvalidClientConfigError(
"Label309Client: base_url is required. Pass the gateway base URL \
(the api_key is an optional opaque bearer; omit it for read-only access)."
.to_string(),
)),
}
}
fn strip_trailing_slash(url: &str) -> String {
url.strip_suffix('/').unwrap_or(url).to_string()
}
pub struct Label309Client {
api_key: Option<String>,
base_url: String,
transport: Box<dyn ClientTransport>,
}
impl Label309Client {
pub fn new(config: Label309ClientConfig) -> Result<Self, InvalidClientConfigError> {
Self::with_transport(config, Box::new(ReqwestClientTransport::new()))
}
pub fn with_transport(
config: Label309ClientConfig,
transport: Box<dyn ClientTransport>,
) -> Result<Self, InvalidClientConfigError> {
let base_url = strip_trailing_slash(&resolve_base_url(&config)?);
Ok(Self {
api_key: config.api_key,
base_url,
transport,
})
}
#[must_use]
pub fn base_url(&self) -> &str {
&self.base_url
}
fn namespace_config(&self) -> NamespaceConfig<'_> {
NamespaceConfig {
api_key: self.api_key.clone(),
base_url: self.base_url.clone(),
transport: self.transport.as_ref(),
}
}
#[must_use]
pub fn poe(&self) -> PoeNamespace<'_> {
PoeNamespace::new(self.namespace_config())
}
#[must_use]
pub fn records(&self) -> RecordsNamespace<'_> {
RecordsNamespace::new(self.namespace_config())
}
#[must_use]
pub fn account(&self) -> AccountNamespace<'_> {
AccountNamespace::new(self.namespace_config())
}
}