use std::time::Duration;
use async_trait::async_trait;
use crate::{BusResult, ContentDigest, Headers, Message};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
#[must_use = "check duplicate() to distinguish a stored message from an idempotent retry or an id collision"]
pub struct PublishReceipt {
stream_sequence: u64,
duplicate: bool,
}
impl PublishReceipt {
pub fn new(stream_sequence: u64, duplicate: bool) -> Self {
Self {
stream_sequence,
duplicate,
}
}
pub fn stream_sequence(&self) -> u64 {
self.stream_sequence
}
pub fn duplicate(&self) -> bool {
self.duplicate
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StreamDelivery {
pub stream_seq: u64,
pub delivery_count: u64,
pub message: Message,
}
#[async_trait]
pub trait StreamCursor: Send {
async fn next(&mut self) -> BusResult<Option<StreamDelivery>>;
async fn ack(&mut self) -> BusResult<()>;
async fn nak(&mut self, delay: Duration) -> BusResult<()>;
async fn term(&mut self, reason: Option<&str>) -> BusResult<()>;
async fn in_progress(&mut self) -> BusResult<()>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DurableOwner<'a> {
Agent(&'a str),
Module(&'a str),
}
#[async_trait]
pub trait Stream: Send + Sync {
type Cursor: StreamCursor;
async fn publish(
&self,
subject: &str,
id: &str,
digest: ContentDigest,
headers: Headers,
) -> BusResult<PublishReceipt>;
async fn consumer(&self, owner: DurableOwner<'_>) -> BusResult<Self::Cursor>;
}