use async_trait::async_trait;
use bytes::Bytes;
use crate::broker::fanout::{ConnectionSink, SubscribeIntent, SubscriptionId};
use crate::error::Result;
use crate::frame::Frame;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PublishOutcome {
pub offset: i64,
pub duplicate: bool,
}
#[async_trait]
pub trait Broker: Send + Sync {
async fn publish(&self, frame: &Frame) -> Result<PublishOutcome>;
async fn subscribe(
&self,
topic: &str,
intent: SubscribeIntent,
sink: ConnectionSink,
) -> Result<SubscriptionId>;
async fn unsubscribe(&self, id: SubscriptionId) -> Result<bool>;
async fn drop_sink(&self, sink_id: u64) -> usize;
async fn replay(&self, topic: &str, from: i64, to: i64) -> Result<Vec<Bytes>>;
async fn snapshot(&self, topic: &str) -> Result<Option<crate::storage::StoredSnapshot>>;
async fn subscriber_count(&self, topic: &str) -> usize;
async fn head_offset(&self, topic: &str) -> i64;
}
pub fn serialize_frame_for_fanout(frame: &Frame, offset: i64) -> Bytes {
let mut buf = Vec::with_capacity(16 + frame.payload.as_ref().map(|p| p.len()).unwrap_or(0));
buf.extend_from_slice(b"OFF:");
buf.extend_from_slice(&offset.to_be_bytes());
if let Some(payload) = frame.payload.as_ref() {
buf.extend_from_slice(payload);
}
Bytes::from(buf)
}
pub type BrokerSubscription = crate::broker::fanout::Subscription;