use std::future::{Future, ready};
use std::num::NonZeroU16;
use std::time::Duration;
use lapin::types::{AMQPValue, FieldTable};
#[cfg(feature = "asyncapi")]
use ruststream::asyncapi::Bindings;
use ruststream::runtime::IntoSource;
use ruststream::{AddressedCopies, RedeliveryAddress, RedeliveryAddressed, SubscriptionSource};
use super::spec::{
Binding, DEAD_LETTER_EXCHANGE, DEAD_LETTER_ROUTING_KEY, QueueKind, QueueSpec, queue_settings,
};
use crate::broker::ConnectedLapinBroker;
use crate::delay::Delay;
use crate::error::AmqpError;
use crate::exchange::RabbitExchange;
use crate::subscriber::LapinSubscriber;
#[derive(Debug, Clone, PartialEq)]
pub struct RabbitQueue {
spec: QueueSpec,
}
impl RabbitQueue {
#[must_use]
pub fn new(name: impl Into<String>) -> Self {
Self {
spec: QueueSpec::new(QueueKind::Classic, name.into()),
}
}
#[must_use]
pub fn durable(mut self, durable: bool) -> Self {
self.spec.durable = durable;
self
}
#[must_use]
pub fn exclusive(mut self, exclusive: bool) -> Self {
self.spec.exclusive = exclusive;
self
}
#[must_use]
pub fn auto_delete(mut self, auto_delete: bool) -> Self {
self.spec.auto_delete = auto_delete;
self
}
pub(crate) const fn spec(&self) -> &QueueSpec {
&self.spec
}
}
queue_settings!(RabbitQueue);
impl IntoSource for RabbitQueue {
type Source = Self;
fn into_source(self) -> Self {
self
}
}
impl SubscriptionSource<ConnectedLapinBroker> for RabbitQueue {
type Subscriber = LapinSubscriber;
type Copies = AddressedCopies;
fn name(&self) -> &str {
&self.spec.name
}
async fn subscribe(
self,
connected: &ConnectedLapinBroker,
) -> Result<Self::Subscriber, AmqpError> {
connected.subscribe(self).await
}
#[cfg(feature = "asyncapi")]
fn channel_bindings(&self) -> Bindings {
crate::bindings::queue_channel(&self.spec)
}
#[cfg(feature = "asyncapi")]
fn operation_bindings(&self) -> Bindings {
crate::bindings::consumer_operation()
}
}
impl RedeliveryAddressed<ConnectedLapinBroker> for RabbitQueue {
fn redelivery_address(
&self,
_connected: &ConnectedLapinBroker,
) -> impl Future<Output = Result<RedeliveryAddress, AmqpError>> + Send {
ready(Ok(RedeliveryAddress::new(self.spec.name.clone())))
}
}