Skip to main content

fakecloud_core/
delivery.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3
4/// Cross-service message delivery.
5///
6/// Services use this to deliver messages to other services without
7/// direct dependencies between service crates. The server wires up
8/// the delivery functions at startup.
9pub struct DeliveryBus {
10    /// Deliver a message to an SQS queue by ARN.
11    sqs_sender: Option<Arc<dyn SqsDelivery>>,
12    /// Publish a message to an SNS topic by ARN.
13    sns_sender: Option<Arc<dyn SnsDelivery>>,
14}
15
16/// Message attribute for SQS delivery from SNS.
17#[derive(Debug, Clone)]
18pub struct SqsMessageAttribute {
19    pub data_type: String,
20    pub string_value: Option<String>,
21    pub binary_value: Option<String>,
22}
23
24/// Trait for delivering messages to SQS queues.
25pub trait SqsDelivery: Send + Sync {
26    fn deliver_to_queue(
27        &self,
28        queue_arn: &str,
29        message_body: &str,
30        attributes: &HashMap<String, String>,
31    );
32
33    /// Deliver with message attributes and FIFO fields
34    fn deliver_to_queue_with_attrs(
35        &self,
36        queue_arn: &str,
37        message_body: &str,
38        message_attributes: &HashMap<String, SqsMessageAttribute>,
39        message_group_id: Option<&str>,
40        message_dedup_id: Option<&str>,
41    ) {
42        // Default implementation: fall back to simple delivery
43        let _ = (message_attributes, message_group_id, message_dedup_id);
44        self.deliver_to_queue(queue_arn, message_body, &HashMap::new());
45    }
46}
47
48/// Trait for publishing messages to SNS topics.
49pub trait SnsDelivery: Send + Sync {
50    fn publish_to_topic(&self, topic_arn: &str, message: &str, subject: Option<&str>);
51}
52
53impl DeliveryBus {
54    pub fn new() -> Self {
55        Self {
56            sqs_sender: None,
57            sns_sender: None,
58        }
59    }
60
61    pub fn with_sqs(mut self, sender: Arc<dyn SqsDelivery>) -> Self {
62        self.sqs_sender = Some(sender);
63        self
64    }
65
66    pub fn with_sns(mut self, sender: Arc<dyn SnsDelivery>) -> Self {
67        self.sns_sender = Some(sender);
68        self
69    }
70
71    /// Send a message to an SQS queue identified by ARN.
72    pub fn send_to_sqs(
73        &self,
74        queue_arn: &str,
75        message_body: &str,
76        attributes: &HashMap<String, String>,
77    ) {
78        if let Some(ref sender) = self.sqs_sender {
79            sender.deliver_to_queue(queue_arn, message_body, attributes);
80        }
81    }
82
83    /// Send a message to an SQS queue with message attributes and FIFO fields.
84    pub fn send_to_sqs_with_attrs(
85        &self,
86        queue_arn: &str,
87        message_body: &str,
88        message_attributes: &HashMap<String, SqsMessageAttribute>,
89        message_group_id: Option<&str>,
90        message_dedup_id: Option<&str>,
91    ) {
92        if let Some(ref sender) = self.sqs_sender {
93            sender.deliver_to_queue_with_attrs(
94                queue_arn,
95                message_body,
96                message_attributes,
97                message_group_id,
98                message_dedup_id,
99            );
100        }
101    }
102
103    /// Publish a message to an SNS topic identified by ARN.
104    pub fn publish_to_sns(&self, topic_arn: &str, message: &str, subject: Option<&str>) {
105        if let Some(ref sender) = self.sns_sender {
106            sender.publish_to_topic(topic_arn, message, subject);
107        }
108    }
109}
110
111impl Default for DeliveryBus {
112    fn default() -> Self {
113        Self::new()
114    }
115}