use std::{error::Error as StdError, sync::Arc};
use async_trait::async_trait;
use regex::Regex;
#[derive(Debug, PartialEq)]
pub enum Status {
Closing,
Closed,
Connecting,
Connected,
Disconnected,
}
pub const QUEUE_NAME_PATTERN: &'static str = r"^[a-z0-9_-]+([\.]{1}[a-z0-9_-]+)*$";
#[async_trait]
pub trait GmqQueue: Send + Sync {
fn name(&self) -> &str;
fn is_recv(&self) -> bool;
fn status(&self) -> Status;
fn set_handler(&mut self, handler: Arc<dyn EventHandler>);
fn clear_handler(&mut self);
fn set_msg_handler(&mut self, handler: Arc<dyn MessageHandler>);
fn connect(&mut self) -> Result<(), Box<dyn StdError>>;
async fn close(&mut self) -> Result<(), Box<dyn StdError + Send + Sync>>;
async fn send_msg(&self, payload: Vec<u8>) -> Result<(), Box<dyn StdError + Send + Sync>>;
}
#[async_trait]
pub trait Message: Send + Sync {
fn payload(&self) -> &[u8];
async fn ack(&self) -> Result<(), Box<dyn StdError + Send + Sync>>;
async fn nack(&self) -> Result<(), Box<dyn StdError + Send + Sync>>;
}
#[async_trait]
pub trait EventHandler: Send + Sync {
async fn on_error(&self, queue: Arc<dyn GmqQueue>, err: Box<dyn StdError + Send + Sync>);
async fn on_status(&self, queue: Arc<dyn GmqQueue>, status: Status);
}
#[async_trait]
pub trait MessageHandler: Send + Sync {
async fn on_message(&self, queue: Arc<dyn GmqQueue>, msg: Box<dyn Message>);
}
impl Copy for Status {}
impl Clone for Status {
fn clone(&self) -> Status {
*self
}
}
pub(crate) fn name_validate(name: &str) -> bool {
let re = Regex::new(QUEUE_NAME_PATTERN).unwrap();
re.is_match(name)
}