mod message;
mod state;
use std::convert::Infallible;
use async_trait::async_trait;
use lapin::{acker::Acker, message::Delivery, Channel};
use crate::{error::HandlerError, Request};
pub use message::Msg;
pub use state::State;
#[async_trait]
pub trait Extract: Sized {
type Error;
async fn extract(req: &mut Request) -> Result<Self, Self::Error>;
}
#[async_trait]
impl Extract for Delivery {
type Error = HandlerError;
async fn extract(req: &mut Request) -> Result<Self, Self::Error> {
req.delivery
.take()
.ok_or(HandlerError::DELIVERY_ALREADY_EXTRACTED)
}
}
#[async_trait]
impl Extract for Acker {
type Error = HandlerError;
async fn extract(req: &mut Request) -> Result<Self, Self::Error> {
req.delivery
.as_mut()
.ok_or(HandlerError::DELIVERY_ALREADY_EXTRACTED)
.map(|d| std::mem::take(&mut d.acker))
}
}
#[async_trait]
impl Extract for Channel {
type Error = Infallible;
async fn extract(req: &mut Request) -> Result<Self, Self::Error> {
Ok(req.channel().clone())
}
}
#[async_trait]
impl<T> Extract for Option<T>
where
T: Extract,
{
type Error = Infallible;
async fn extract(req: &mut Request) -> Result<Self, Self::Error> {
Ok(Extract::extract(req).await.ok())
}
}
#[async_trait]
impl<T> Extract for Result<T, <T as Extract>::Error>
where
T: Extract,
{
type Error = Infallible;
async fn extract(req: &mut Request) -> Result<Self, Self::Error> {
Ok(Extract::extract(req).await)
}
}