use std::{future::Future, pin::Pin, sync::Arc};
#[cfg(feature = "rustls")]
use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer};
pub type AuthTokenFn =
Arc<dyn Fn() -> Pin<Box<dyn Future<Output = Option<String>> + Send>> + Send + Sync>;
pub struct NoReconnect;
pub struct Reconnecting<F>(pub(crate) F);
pub struct WStompConfig<U, R = NoReconnect> {
pub(crate) url: U,
pub(crate) opts: WStompConfigOpts,
pub(crate) reconnect: R,
}
#[derive(Clone)]
pub struct WStompConfigOpts {
pub ssl: bool,
pub auth_token: Option<AuthTokenFn>,
pub login: Option<String>,
pub passcode: Option<String>,
#[cfg(feature = "rustls")]
pub cert_chain: Option<Vec<CertificateDer<'static>>>,
#[cfg(feature = "rustls")]
pub key_der: Option<Arc<PrivateKeyDer<'static>>>,
#[cfg(feature = "rustls")]
pub ca_certs: Option<Vec<CertificateDer<'static>>>,
pub additional_headers: Vec<(String, String)>,
pub client: Option<awc::Client>,
pub retry_initial_interval: u64,
pub retry_max_interval: u64,
pub retry_multiplier: f64,
pub retry_max_elapsed_time: Option<u64>,
}
impl Default for WStompConfigOpts {
fn default() -> Self {
Self {
ssl: Default::default(),
auth_token: Default::default(),
login: Default::default(),
passcode: Default::default(),
#[cfg(feature = "rustls")]
cert_chain: Default::default(),
#[cfg(feature = "rustls")]
key_der: Default::default(),
#[cfg(feature = "rustls")]
ca_certs: Default::default(),
additional_headers: Default::default(),
client: Default::default(),
retry_initial_interval: 3,
retry_max_interval: 60,
retry_multiplier: 1.2,
retry_max_elapsed_time: None,
}
}
}
impl<U> WStompConfig<U, NoReconnect> {
pub fn new(url: U) -> Self {
Self {
url,
opts: WStompConfigOpts::default(),
reconnect: NoReconnect,
}
}
}
impl<U, R> WStompConfig<U, R> {
pub fn get_url(&self) -> &U {
&self.url
}
pub fn get_opts(&self) -> &WStompConfigOpts {
&self.opts
}
pub fn into_parts(self) -> (U, WStompConfigOpts) {
(self.url, self.opts)
}
pub fn ssl(mut self) -> Self {
self.opts.ssl = true;
self
}
pub fn auth_token(mut self, auth_token: impl Into<String>) -> Self {
let token = auth_token.into();
self.opts.auth_token = Some(Arc::new(move || {
let token = token.clone();
Box::pin(async move { Some(token) })
}));
self
}
pub fn auth_token_fn<F, Fut>(mut self, f: F) -> Self
where
F: Fn() -> Fut + Send + Sync + 'static,
Fut: Future<Output = Option<String>> + Send + 'static,
{
self.opts.auth_token = Some(Arc::new(move || Box::pin(f())));
self
}
pub fn login(mut self, login: impl Into<String>) -> Self {
self.opts.login = Some(login.into());
self
}
pub fn passcode(mut self, passcode: impl Into<String>) -> Self {
self.opts.passcode = Some(passcode.into());
self
}
#[cfg(feature = "rustls")]
pub fn cert(mut self, cert_chain: impl Into<Vec<CertificateDer<'static>>>) -> Self {
self.opts.cert_chain = Some(cert_chain.into());
self
}
#[cfg(feature = "rustls")]
pub fn key(mut self, key: impl Into<Arc<PrivateKeyDer<'static>>>) -> Self {
self.opts.key_der = Some(key.into());
self
}
#[cfg(feature = "rustls")]
pub fn ca_certs(mut self, ca_certs: impl Into<Vec<CertificateDer<'static>>>) -> Self {
self.opts.ca_certs = Some(ca_certs.into());
self
}
pub fn add_headers(mut self, additional_headers: Vec<(String, String)>) -> Self {
self.opts.additional_headers.extend(additional_headers);
self
}
pub fn client(mut self, client: awc::Client) -> Self {
self.opts.client = Some(client);
self
}
pub fn retry_initial_interval(mut self, seconds: u64) -> Self {
self.opts.retry_initial_interval = seconds;
self
}
pub fn retry_max_interval(mut self, seconds: u64) -> Self {
self.opts.retry_max_interval = seconds;
self
}
pub fn retry_multiplier(mut self, multiplier: f64) -> Self {
self.opts.retry_multiplier = multiplier;
self
}
pub fn retry_max_elapsed_time(mut self, seconds: u64) -> Self {
self.opts.retry_max_elapsed_time = Some(seconds);
self
}
}