use core::fmt;
use std::convert::Infallible;
use async_trait::async_trait;
use lapin::{
message::Delivery,
types::{AMQPValue, LongString},
};
use uuid::Uuid;
use crate::{Extract, Request};
#[derive(Debug, Clone, PartialEq)]
pub struct ReqId(pub AMQPValue);
impl ReqId {
pub fn new() -> Self {
let uuid = Uuid::new_v4();
let amqp_value = AMQPValue::LongString(LongString::from(uuid.to_string()));
Self(amqp_value)
}
pub(crate) fn from_delivery(delivery: &Delivery) -> Self {
let Some(headers) = delivery.properties.headers() else {
return Self::new();
};
let Some(req_id) = headers.inner().get("req_id") else {
return Self::new();
};
Self(req_id.clone())
}
}
impl Default for ReqId {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for ReqId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
AMQPValue::LongString(req_id) => req_id.fmt(f),
AMQPValue::Boolean(b) => b.fmt(f),
AMQPValue::ShortShortInt(v) => v.fmt(f),
AMQPValue::ShortShortUInt(v) => v.fmt(f),
AMQPValue::ShortInt(v) => v.fmt(f),
AMQPValue::ShortUInt(v) => v.fmt(f),
AMQPValue::LongInt(v) => v.fmt(f),
AMQPValue::LongUInt(v) => v.fmt(f),
AMQPValue::LongLongInt(v) => v.fmt(f),
AMQPValue::Float(v) => v.fmt(f),
AMQPValue::Double(v) => v.fmt(f),
AMQPValue::DecimalValue(v) => write!(f, "{v:?}"),
AMQPValue::ShortString(v) => write!(f, "{v:?}"),
AMQPValue::FieldArray(v) => write!(f, "{v:?}"),
AMQPValue::Timestamp(v) => write!(f, "{v:?}"),
AMQPValue::FieldTable(v) => write!(f, "{v:?}"),
AMQPValue::ByteArray(v) => write!(f, "{v:?}"),
AMQPValue::Void => write!(f, "Void"),
}
}
}
#[async_trait]
impl<S> Extract<S> for ReqId
where
S: Send + Sync,
{
type Error = Infallible;
async fn extract(req: &mut Request<S>) -> Result<Self, Self::Error> {
Ok(req.req_id().clone())
}
}