use crate::error::Result;
use crate::types::{Event, PublishOptions, ReceivedEvent, SubscribeOptions};
use crate::types::BoxFuture;
use async_trait::async_trait;
pub mod memory;
#[cfg(feature = "nats")]
pub mod nats;
#[async_trait]
pub trait EventProvider: Send + Sync {
async fn publish(&self, event: &Event) -> Result<u64>;
async fn subscribe_durable(
&self,
consumer_name: &str,
filter_subject: &str,
) -> Result<Box<dyn Subscription>>;
async fn subscribe(
&self,
filter_subject: &str,
) -> Result<Box<dyn Subscription>>;
async fn history(
&self,
filter_subject: Option<&str>,
limit: usize,
) -> Result<Vec<Event>>;
async fn unsubscribe(&self, consumer_name: &str) -> Result<()>;
async fn info(&self) -> Result<ProviderInfo>;
fn build_subject(&self, category: &str, topic: &str) -> String {
format!("{}.{}.{}", self.subject_prefix(), category, topic)
}
fn category_subject(&self, category: &str) -> String {
format!("{}.{}.>", self.subject_prefix(), category)
}
fn subject_prefix(&self) -> &str;
fn name(&self) -> &str;
async fn publish_with_options(&self, event: &Event, _opts: &PublishOptions) -> Result<u64> {
self.publish(event).await
}
async fn subscribe_durable_with_options(
&self,
consumer_name: &str,
filter_subject: &str,
_opts: &SubscribeOptions,
) -> Result<Box<dyn Subscription>> {
self.subscribe_durable(consumer_name, filter_subject).await
}
async fn subscribe_with_options(
&self,
filter_subject: &str,
_opts: &SubscribeOptions,
) -> Result<Box<dyn Subscription>> {
self.subscribe(filter_subject).await
}
async fn health(&self) -> Result<bool> {
self.info().await.map(|_| true)
}
}
#[async_trait]
pub trait Subscription: Send + Sync {
async fn next(&mut self) -> Result<Option<ReceivedEvent>>;
async fn next_manual_ack(&mut self) -> Result<Option<PendingEvent>>;
}
pub struct PendingEvent {
pub received: ReceivedEvent,
ack_fn: Box<dyn FnOnce() -> BoxFuture<'static, Result<()>> + Send>,
nak_fn: Box<dyn FnOnce() -> BoxFuture<'static, Result<()>> + Send>,
}
impl PendingEvent {
pub fn new(
received: ReceivedEvent,
ack_fn: impl FnOnce() -> BoxFuture<'static, Result<()>> + Send + 'static,
nak_fn: impl FnOnce() -> BoxFuture<'static, Result<()>> + Send + 'static,
) -> Self {
Self {
received,
ack_fn: Box::new(ack_fn),
nak_fn: Box::new(nak_fn),
}
}
pub async fn ack(self) -> Result<()> {
(self.ack_fn)().await
}
pub async fn nak(self) -> Result<()> {
(self.nak_fn)().await
}
}
#[derive(Debug, Clone)]
pub struct ProviderInfo {
pub provider: String,
pub messages: u64,
pub bytes: u64,
pub consumers: usize,
}