use lapin::types::{AMQPValue, FieldTable, ShortString};
use ruststream::SubscriptionSource;
use crate::broker::LapinBroker;
use crate::delay::Delay;
use crate::error::AmqpError;
use crate::exchange::RabbitExchange;
use crate::subscriber::LapinSubscriber;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum QueueType {
Classic,
Quorum,
}
impl QueueType {
pub(crate) fn as_str(self) -> &'static str {
match self {
Self::Classic => "classic",
Self::Quorum => "quorum",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RabbitQueue {
name: String,
durable: bool,
exclusive: bool,
auto_delete: bool,
queue_type: Option<QueueType>,
bindings: Vec<(RabbitExchange, String)>,
arguments: FieldTable,
prefetch: Option<u16>,
delay: Option<Delay>,
}
impl RabbitQueue {
#[must_use]
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
durable: true,
exclusive: false,
auto_delete: false,
queue_type: None,
bindings: Vec::new(),
arguments: FieldTable::default(),
prefetch: None,
delay: None,
}
}
#[must_use]
pub fn durable(mut self, durable: bool) -> Self {
self.durable = durable;
self
}
#[must_use]
pub fn exclusive(mut self, exclusive: bool) -> Self {
self.exclusive = exclusive;
self
}
#[must_use]
pub fn auto_delete(mut self, auto_delete: bool) -> Self {
self.auto_delete = auto_delete;
self
}
#[must_use]
pub fn queue_type(mut self, queue_type: QueueType) -> Self {
self.queue_type = Some(queue_type);
self
}
#[must_use]
pub fn bind(mut self, exchange: RabbitExchange, routing_key: impl Into<String>) -> Self {
self.bindings.push((exchange, routing_key.into()));
self
}
#[must_use]
pub fn dead_letter_exchange(mut self, exchange: impl Into<String>) -> Self {
self.arguments.insert(
ShortString::from("x-dead-letter-exchange"),
AMQPValue::LongString(exchange.into().into()),
);
self
}
#[must_use]
pub fn dead_letter_routing_key(mut self, routing_key: impl Into<String>) -> Self {
self.arguments.insert(
ShortString::from("x-dead-letter-routing-key"),
AMQPValue::LongString(routing_key.into().into()),
);
self
}
#[must_use]
pub fn argument(mut self, name: impl Into<String>, value: AMQPValue) -> Self {
self.arguments.insert(ShortString::from(name.into()), value);
self
}
#[must_use]
pub fn arguments(mut self, arguments: FieldTable) -> Self {
self.arguments = arguments;
self
}
#[must_use]
pub fn prefetch(mut self, prefetch: u16) -> Self {
self.prefetch = Some(prefetch);
self
}
#[must_use]
pub fn delay(mut self, delay: Delay) -> Self {
self.delay = Some(delay);
self
}
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
pub(crate) fn is_durable(&self) -> bool {
self.durable
}
pub(crate) fn is_exclusive(&self) -> bool {
self.exclusive
}
pub(crate) fn is_auto_delete(&self) -> bool {
self.auto_delete
}
pub(crate) fn queue_type_or(&self, broker_default: Option<QueueType>) -> Option<QueueType> {
self.queue_type.or(broker_default)
}
pub(crate) fn bindings(&self) -> &[(RabbitExchange, String)] {
&self.bindings
}
pub(crate) fn declare_arguments(&self) -> &FieldTable {
&self.arguments
}
pub(crate) fn prefetch_or(&self, broker_default: Option<u16>) -> Option<u16> {
self.prefetch.or(broker_default)
}
pub(crate) fn delay_config(&self) -> Option<&Delay> {
self.delay.as_ref()
}
}
impl SubscriptionSource<LapinBroker> for RabbitQueue {
type Subscriber = LapinSubscriber;
fn name(&self) -> &str {
&self.name
}
async fn subscribe(self, broker: &LapinBroker) -> Result<Self::Subscriber, AmqpError> {
broker.subscribe(self).await
}
}
#[cfg(feature = "testing")]
impl SubscriptionSource<crate::testing::LapinTestBroker> for RabbitQueue {
type Subscriber = crate::testing::LapinTestSubscriber;
fn name(&self) -> &str {
&self.name
}
async fn subscribe(
self,
broker: &crate::testing::LapinTestBroker,
) -> Result<Self::Subscriber, AmqpError> {
broker.subscribe(self.name).await
}
}