use crate::api::connection::Connection;
use crate::config::Config;
use crate::error::ConnectError;
use crate::observe::{SharedMetrics, noop_metrics};
use crate::sasl::SaslProfile;
use crate::transport::{Address, TlsConfig};
pub struct ConnectionBuilder {
url: String,
config: Config,
metrics: SharedMetrics,
sasl: Option<SaslProfile>,
tls: TlsConfig,
reconnecting: bool,
}
impl std::fmt::Debug for ConnectionBuilder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConnectionBuilder")
.field("url", &self.url)
.field("config", &self.config)
.field("sasl", &self.sasl)
.field("tls", &self.tls)
.finish_non_exhaustive()
}
}
impl ConnectionBuilder {
pub fn new(url: impl Into<String>) -> Self {
ConnectionBuilder {
url: url.into(),
config: Config::default(),
metrics: noop_metrics(),
sasl: None,
tls: TlsConfig::default(),
reconnecting: false,
}
}
pub fn config(mut self, config: Config) -> Self {
self.config = config;
self
}
pub fn low_latency(mut self) -> Self {
self.config = Config::low_latency();
self
}
pub fn high_throughput(mut self) -> Self {
self.config = Config::high_throughput();
self
}
pub fn metrics(mut self, metrics: SharedMetrics) -> Self {
self.metrics = metrics;
self
}
pub fn sasl(mut self, profile: SaslProfile) -> Self {
self.sasl = Some(profile);
self
}
pub fn tls(mut self, tls: TlsConfig) -> Self {
self.tls = tls;
self
}
pub fn add_root_ca_pem(mut self, pem: impl Into<Vec<u8>>) -> Self {
self.tls.root_ca_pem.push(pem.into());
self
}
pub fn client_auth_pem(mut self, cert_chain: impl Into<Vec<u8>>, key: impl Into<Vec<u8>>) -> Self {
self.tls.client_auth_pem = Some((cert_chain.into(), key.into()));
self
}
pub fn tls_server_name(mut self, name: impl Into<String>) -> Self {
self.tls.server_name = Some(name.into());
self
}
pub fn webpki_roots(mut self, enabled: bool) -> Self {
self.tls.webpki_roots = enabled;
self
}
pub fn danger_accept_invalid_certs(mut self, accept: bool) -> Self {
self.tls.danger_accept_invalid_certs = accept;
self
}
pub fn reconnecting(mut self, enabled: bool) -> Self {
self.reconnecting = enabled;
self
}
pub async fn connect(mut self) -> Result<Connection, ConnectError> {
let addr = Address::parse(&self.url)?;
if self.config.connection.hostname.is_none() {
self.config.connection.hostname = Some(addr.host.clone());
}
let profile = self.sasl.take().unwrap_or_else(|| {
SaslProfile::from_credentials(addr.username.clone(), addr.password.clone())
});
if self.reconnecting {
crate::resilience::transparent::connect_supervised(
addr,
self.config,
self.metrics,
profile,
self.tls,
)
.await
} else {
Connection::establish(addr, self.config, self.metrics, profile, self.tls).await
}
}
}