use std::ops::Deref;
#[cfg(feature = "k8s")]
use std::sync::Arc;
#[cfg(feature = "k8s")]
use tokio::sync::watch;
#[derive(Clone)]
pub struct FlatbedContext<C> {
inner: C,
#[cfg(feature = "nats")]
pub nats_client: async_nats::Client,
#[cfg(feature = "nats")]
pub jetstream: async_nats::jetstream::Context,
#[cfg(feature = "nats")]
pub stream_replicas: usize,
#[cfg(feature = "k8s")]
pub kube_client: kube::Client,
#[cfg(feature = "k8s")]
pub is_leader_tx: Arc<watch::Sender<bool>>,
#[cfg(feature = "k8s")]
is_leader_rx: watch::Receiver<bool>,
#[cfg(feature = "k8s")]
pub ha_mode: bool,
}
impl<C> Deref for FlatbedContext<C> {
type Target = C;
fn deref(&self) -> &C {
&self.inner
}
}
#[cfg(feature = "nats")]
impl<C> crate::nats::HasJetStream for FlatbedContext<C> {
fn jetstream(&self) -> &async_nats::jetstream::Context {
&self.jetstream
}
fn stream_replicas(&self) -> usize {
self.stream_replicas
}
}
#[cfg(feature = "nats")]
impl<C> crate::nats::HasNatsClient for FlatbedContext<C> {
fn nats_client(&self) -> &async_nats::Client {
&self.nats_client
}
}
#[cfg(feature = "k8s")]
impl<C> crate::k8s::HasKubeClient for FlatbedContext<C> {
fn kube_client(&self) -> &kube::Client {
&self.kube_client
}
}
#[cfg(feature = "k8s")]
impl<C> crate::k8s::HasLeaderElection for FlatbedContext<C> {
fn is_leader_rx(&self) -> watch::Receiver<bool> {
self.is_leader_rx.clone()
}
fn ha_enabled(&self) -> bool {
self.ha_mode
}
}
impl<C> FlatbedContext<C> {
pub fn builder(inner: C) -> FlatbedContextBuilder<C> {
FlatbedContextBuilder {
inner,
#[cfg(feature = "nats")]
nats_client: None,
#[cfg(feature = "nats")]
jetstream: None,
#[cfg(feature = "nats")]
stream_replicas: None,
#[cfg(feature = "k8s")]
kube_client: None,
#[cfg(feature = "k8s")]
is_leader_tx: None,
#[cfg(feature = "k8s")]
is_leader_rx: None,
#[cfg(feature = "k8s")]
ha_mode: None,
}
}
pub fn inner(&self) -> &C {
&self.inner
}
}
pub struct FlatbedContextBuilder<C> {
inner: C,
#[cfg(feature = "nats")]
nats_client: Option<async_nats::Client>,
#[cfg(feature = "nats")]
jetstream: Option<async_nats::jetstream::Context>,
#[cfg(feature = "nats")]
stream_replicas: Option<usize>,
#[cfg(feature = "k8s")]
kube_client: Option<kube::Client>,
#[cfg(feature = "k8s")]
is_leader_tx: Option<Arc<watch::Sender<bool>>>,
#[cfg(feature = "k8s")]
is_leader_rx: Option<watch::Receiver<bool>>,
#[cfg(feature = "k8s")]
ha_mode: Option<bool>,
}
impl<C> FlatbedContextBuilder<C> {
#[cfg(feature = "nats")]
pub fn nats_client(mut self, nats_client: async_nats::Client) -> Self {
self.nats_client = Some(nats_client);
self
}
#[cfg(feature = "nats")]
pub fn jetstream(mut self, jetstream: async_nats::jetstream::Context) -> Self {
self.jetstream = Some(jetstream);
self
}
#[cfg(feature = "nats")]
pub fn stream_replicas(mut self, n: usize) -> Self {
self.stream_replicas = Some(n);
self
}
#[cfg(feature = "k8s")]
pub fn kube_client(mut self, kube_client: kube::Client) -> Self {
self.kube_client = Some(kube_client);
self
}
#[cfg(feature = "k8s")]
pub fn leader_election(
mut self,
is_leader_tx: Arc<watch::Sender<bool>>,
is_leader_rx: watch::Receiver<bool>,
ha_mode: bool,
) -> Self {
self.is_leader_tx = Some(is_leader_tx);
self.is_leader_rx = Some(is_leader_rx);
self.ha_mode = Some(ha_mode);
self
}
pub fn build(self) -> FlatbedContext<C> {
FlatbedContext {
inner: self.inner,
#[cfg(feature = "nats")]
nats_client: self.nats_client.expect("nats_client is required"),
#[cfg(feature = "nats")]
jetstream: self.jetstream.expect("jetstream is required"),
#[cfg(feature = "nats")]
stream_replicas: self.stream_replicas.unwrap_or(1),
#[cfg(feature = "k8s")]
kube_client: self.kube_client.expect("kube_client is required"),
#[cfg(feature = "k8s")]
is_leader_tx: self.is_leader_tx.expect("leader_election is required"),
#[cfg(feature = "k8s")]
is_leader_rx: self.is_leader_rx.expect("leader_election is required"),
#[cfg(feature = "k8s")]
ha_mode: self.ha_mode.expect("leader_election is required"),
}
}
}