use crate::output_stream::num_bytes::NumBytes;
mod sealed {
pub trait DeliverySealed {}
pub trait ReplaySealed {}
}
pub trait Delivery:
sealed::DeliverySealed + Clone + Copy + std::fmt::Debug + PartialEq + Eq + Send + Sync + 'static
{
fn guarantee(self) -> DeliveryGuarantee;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BestEffortDelivery;
impl sealed::DeliverySealed for BestEffortDelivery {}
impl Delivery for BestEffortDelivery {
fn guarantee(self) -> DeliveryGuarantee {
DeliveryGuarantee::BestEffort
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ReliableDelivery;
impl sealed::DeliverySealed for ReliableDelivery {}
impl Delivery for ReliableDelivery {
fn guarantee(self) -> DeliveryGuarantee {
DeliveryGuarantee::ReliableForActiveSubscribers
}
}
pub trait Replay:
sealed::ReplaySealed + Clone + Copy + std::fmt::Debug + PartialEq + Eq + Send + Sync + 'static
{
fn replay_retention(self) -> Option<ReplayRetention>;
fn replay_enabled(self) -> bool;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NoReplay;
impl sealed::ReplaySealed for NoReplay {}
impl Replay for NoReplay {
fn replay_retention(self) -> Option<ReplayRetention> {
None
}
fn replay_enabled(self) -> bool {
false
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ReplayEnabled {
pub replay_retention: ReplayRetention,
}
impl ReplayEnabled {
#[must_use]
pub fn new(replay_retention: ReplayRetention) -> Self {
replay_retention.assert_non_zero("replay_retention");
Self { replay_retention }
}
}
impl sealed::ReplaySealed for ReplayEnabled {}
impl Replay for ReplayEnabled {
fn replay_retention(self) -> Option<ReplayRetention> {
Some(self.replay_retention)
}
fn replay_enabled(self) -> bool {
true
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DeliveryGuarantee {
BestEffort,
ReliableForActiveSubscribers,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReplayRetention {
LastChunks(usize),
LastBytes(NumBytes),
All,
}
impl ReplayRetention {
pub(crate) fn assert_non_zero(self, parameter_name: &str) {
match self {
ReplayRetention::LastChunks(0) => {
panic!("{parameter_name} must retain at least one chunk");
}
ReplayRetention::LastBytes(bytes) if bytes.bytes() == 0 => {
panic!("{parameter_name} must retain at least one byte");
}
ReplayRetention::LastChunks(_)
| ReplayRetention::LastBytes(_)
| ReplayRetention::All => {}
}
}
}