1use chrono::{DateTime, Utc};
2use parking_lot::RwLock;
3use std::collections::{BTreeMap, HashMap};
4use std::sync::Arc;
5
6#[derive(Debug, Clone)]
7pub struct SnsTopic {
8 pub topic_arn: String,
9 pub name: String,
10 pub attributes: HashMap<String, String>,
11 pub tags: Vec<(String, String)>,
12 pub is_fifo: bool,
13 pub created_at: DateTime<Utc>,
14}
15
16#[derive(Debug, Clone)]
17pub struct SnsSubscription {
18 pub subscription_arn: String,
19 pub topic_arn: String,
20 pub protocol: String,
21 pub endpoint: String,
22 pub owner: String,
23 pub attributes: HashMap<String, String>,
24 pub confirmed: bool,
25 pub confirmation_token: Option<String>,
27}
28
29#[derive(Debug, Clone)]
31pub struct MessageAttribute {
32 pub data_type: String,
33 pub string_value: Option<String>,
34 pub binary_value: Option<Vec<u8>>,
35}
36
37#[derive(Debug, Clone)]
38pub struct PublishedMessage {
39 pub message_id: String,
40 pub topic_arn: String,
41 pub message: String,
42 pub subject: Option<String>,
43 pub message_attributes: HashMap<String, MessageAttribute>,
44 pub message_group_id: Option<String>,
45 pub message_dedup_id: Option<String>,
46 pub timestamp: DateTime<Utc>,
47}
48
49#[derive(Debug, Clone)]
50pub struct PlatformApplication {
51 pub arn: String,
52 pub name: String,
53 pub platform: String,
54 pub attributes: HashMap<String, String>,
55 pub endpoints: HashMap<String, PlatformEndpoint>,
56}
57
58#[derive(Debug, Clone)]
59pub struct PlatformEndpoint {
60 pub arn: String,
61 pub token: String,
62 pub attributes: HashMap<String, String>,
63 pub enabled: bool,
64 pub messages: Vec<PublishedMessage>,
65}
66
67#[derive(Debug, Clone)]
69pub struct LambdaInvocation {
70 pub function_arn: String,
71 pub message: String,
72 pub subject: Option<String>,
73 pub timestamp: DateTime<Utc>,
74}
75
76#[derive(Debug, Clone)]
78pub struct SentEmail {
79 pub email_address: String,
80 pub message: String,
81 pub subject: Option<String>,
82 pub topic_arn: String,
83 pub timestamp: DateTime<Utc>,
84}
85
86pub struct SnsState {
87 pub account_id: String,
88 pub region: String,
89 pub endpoint: String,
90 pub topics: BTreeMap<String, SnsTopic>, pub subscriptions: BTreeMap<String, SnsSubscription>, pub published: Vec<PublishedMessage>,
93 pub platform_applications: BTreeMap<String, PlatformApplication>,
94 pub sms_attributes: HashMap<String, String>,
95 pub opted_out_numbers: Vec<String>,
96 pub sms_messages: Vec<(String, String)>, pub lambda_invocations: Vec<LambdaInvocation>,
99 pub sent_emails: Vec<SentEmail>,
101}
102
103impl SnsState {
104 pub fn new(account_id: &str, region: &str, endpoint: &str) -> Self {
105 Self {
106 account_id: account_id.to_string(),
107 region: region.to_string(),
108 endpoint: endpoint.to_string(),
109 topics: BTreeMap::new(),
110 subscriptions: BTreeMap::new(),
111 published: Vec::new(),
112 platform_applications: BTreeMap::new(),
113 sms_attributes: HashMap::new(),
114 opted_out_numbers: Vec::new(),
115 sms_messages: Vec::new(),
116 lambda_invocations: Vec::new(),
117 sent_emails: Vec::new(),
118 }
119 }
120
121 pub fn reset(&mut self) {
122 self.topics.clear();
123 self.subscriptions.clear();
124 self.published.clear();
125 self.platform_applications.clear();
126 self.sms_attributes.clear();
127 self.opted_out_numbers.clear();
128 self.sms_messages.clear();
129 self.lambda_invocations.clear();
130 self.sent_emails.clear();
131 }
132
133 pub fn seed_default_opted_out(&mut self) {
135 if self.opted_out_numbers.is_empty() {
136 self.opted_out_numbers.push("+15005550099".to_string());
137 self.opted_out_numbers.push("+447428545399".to_string());
138 }
139 }
140}
141
142pub type SharedSnsState = Arc<RwLock<SnsState>>;