pub mod nats;
use crate::error::ServiceResult;
use std::sync::Arc;
#[cfg(feature = "nats")]
pub use nats::{NatsClient, SharedNatsClient};
#[async_trait::async_trait]
pub trait MessageQueue: Send + Sync + 'static {
async fn publish(&self, topic: &str, message: Vec<u8>) -> ServiceResult<()>;
async fn subscribe(&self, topic: &str) -> ServiceResult<Box<dyn MessageStream>>;
async fn health_check(&self) -> ServiceResult<()>;
}
#[async_trait::async_trait]
pub trait MessageStream: Send + Sync + 'static {
async fn next(&mut self) -> ServiceResult<Option<Message>>;
}
#[derive(Debug, Clone)]
pub struct Message {
pub payload: Vec<u8>,
pub subject: String,
pub headers: std::collections::HashMap<String, String>,
}
impl Message {
pub fn new(subject: impl Into<String>, payload: Vec<u8>) -> Self {
Self {
payload,
subject: subject.into(),
headers: std::collections::HashMap::new(),
}
}
pub fn with_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.headers.insert(key.into(), value.into());
self
}
}
pub type BoxedMessageQueue = Box<dyn MessageQueue>;
pub type SharedMessageQueue = Arc<dyn MessageQueue>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_message_creation() {
let msg = Message::new("test.subject", b"hello world".to_vec());
assert_eq!(msg.subject, "test.subject");
assert_eq!(msg.payload, b"hello world");
}
#[test]
fn test_message_with_header() {
let msg = Message::new("test.subject", b"hello".to_vec())
.with_header("content-type", "text/plain");
assert_eq!(msg.headers.get("content-type"), Some(&"text/plain".to_string()));
}
}