email_clients/clients/memory.rs
1use crate::configuration::EmailConfiguration;
2use async_trait::async_trait;
3use std::sync::mpsc;
4use std::sync::mpsc::SyncSender;
5
6use crate::email::{EmailAddress, EmailObject};
7use crate::errors::EmailError;
8use crate::traits::EmailTrait;
9
10#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, Default, PartialOrd, PartialEq)]
11pub struct MemoryConfig {
12 pub sender: EmailAddress,
13}
14
15impl MemoryConfig {
16 /// Generates a new `MemoryConfig`.
17 ///
18 /// # Parameters
19 /// - `sender`: A `String` that will be used as the sender of the `MemoryConfig`.
20 ///
21 /// # Returns
22 /// A new instance of `MemoryConfig` with the `sender` property set to the provided `String`.
23 ///
24 /// # Examples
25 /// ```rust
26 /// use email_clients::clients::memory::MemoryConfig;
27 ///
28 /// let config = MemoryConfig::new("sender@example.com");
29 /// assert_eq!(config.sender.to_string(), "sender@example.com");
30 /// ```
31 pub fn new(sender: impl Into<EmailAddress>) -> Self {
32 Self {
33 sender: sender.into(),
34 }
35 }
36}
37
38impl From<String> for MemoryConfig {
39 /// Converts a `String` into a `MemoryConfig`.
40 ///
41 /// # Parameters
42 /// - `value`: A `String` value which will be used to initialize a `MemoryConfig` instance.
43 ///
44 /// # Returns
45 /// A new instance of `MemoryConfig` with the `sender` property set to the provided `String`.
46 ///
47 /// # Examples
48 /// ```rust
49 /// use email_clients::clients::memory::MemoryConfig;
50 /// let value = String::from("sender@example.com");
51 /// let config = MemoryConfig::from(value);
52 /// assert_eq!(config.sender.to_string(), "sender@example.com");
53 /// ```
54 fn from(value: String) -> Self {
55 Self::new(value.as_str())
56 }
57}
58
59impl From<MemoryConfig> for EmailConfiguration {
60 /// Implementation of From trait to convert MemoryConfig into EmailConfiguration
61 ///
62 /// # Example
63 ///
64 /// ```rust
65 /// # use email_clients::configuration::EmailConfiguration;
66 /// # use email_clients::clients::memory::MemoryConfig;
67 /// #
68 /// let memory_config = MemoryConfig::new("sender@example.com");
69 /// let email_config: EmailConfiguration = memory_config.into();
70 /// #
71 /// # match email_config {
72 /// # EmailConfiguration::Memory(mc) => {
73 /// # assert_eq!(mc.sender.to_string(), "sender@example.com");
74 /// # },
75 /// # _ => panic!("Invalid conversion"),
76 /// # }
77 /// ```
78 fn from(value: MemoryConfig) -> Self {
79 EmailConfiguration::Memory(value)
80 }
81}
82
83#[derive(Clone, Debug)]
84pub struct MemoryClient {
85 sender: EmailAddress,
86 tx: SyncSender<EmailObject>,
87}
88
89impl Default for MemoryClient {
90 /// `Default` implementation for `MemoryClient`.
91 ///
92 /// This method will return a `MemoryClient` instance with an empty sender and a `SyncSender<EmailObject>`
93 /// with a channel buffer size of 5.
94 ///
95 /// # Returns
96 /// A `MemoryClient` instance with the default configuration.
97 ///
98 /// # Examples
99 ///
100 /// ```rust
101 /// use email_clients::clients::memory::MemoryClient;
102 /// use email_clients::traits::EmailTrait;
103 ///
104 /// let default_client = MemoryClient::default();
105 /// // Gets the default sender which is an empty string
106 /// assert_eq!(default_client.get_sender().to_string(), "");
107 /// ```
108 fn default() -> Self {
109 let (tx, _) = mpsc::sync_channel(5 /* usize */);
110 Self {
111 sender: "".into(),
112 tx,
113 }
114 }
115}
116
117impl MemoryClient {
118 /// Initializes a new `MemoryClient` with the provided `MemoryConfig`.
119 ///
120 /// # Parameters
121 /// - `config`: A `MemoryConfig` instance that will be used to initialize the `MemoryClient`.
122 ///
123 /// # Returns
124 /// A new instance of `MemoryClient` with the `sender` and `SyncSender<EmailObject>` set per the provided `MemoryConfig`.
125 ///
126 /// # Examples
127 /// ```rust
128 /// # use email_clients::clients::memory::{MemoryConfig, MemoryClient};
129 /// # use email_clients::traits::EmailTrait;
130 ///
131 /// let config = MemoryConfig::new("sender@example.com");
132 /// let client = MemoryClient::new(config);
133 /// assert_eq!(client.get_sender().to_string(), "sender@example.com");
134 /// ```
135 pub fn new(config: MemoryConfig) -> Self {
136 let (tx, _) = mpsc::sync_channel(5 /* usize */);
137
138 Self {
139 sender: config.sender,
140 tx,
141 }
142 }
143
144 /// Initializes a new `MemoryClient` with the provided `MemoryConfig` and `SyncSender<EmailObject>`.
145 ///
146 /// # Parameters
147 /// - `config`: A `MemoryConfig` instance that will be used to initialize the `MemoryClient`.
148 /// - `tx`: A `SyncSender<EmailObject>` instance that will be used for sending emails.
149 ///
150 /// # Returns
151 /// A new instance of `MemoryClient` with the `sender` and `SyncSender<EmailObject>` set per the provided parameters.
152 ///
153 /// # Examples
154 /// ```rust
155 /// # use std::sync::mpsc::sync_channel;
156 /// # use email_clients::clients::memory::{MemoryConfig, MemoryClient};
157 /// # use email_clients::email::EmailObject;
158 /// # use email_clients::traits::EmailTrait;
159 ///
160 /// let config = MemoryConfig::new("sender@example.com");
161 /// let (tx, rx) = sync_channel(2);
162 /// let client = MemoryClient::with_tx(config, tx.clone());
163 /// assert_eq!(client.get_sender().to_string(), "sender@example.com");
164 /// ```
165 pub fn with_tx(config: MemoryConfig, tx: SyncSender<EmailObject>) -> Self {
166 Self {
167 sender: config.sender,
168 tx,
169 }
170 }
171}
172
173#[async_trait]
174impl EmailTrait for MemoryClient {
175 /// Returns the sender email address used for the `MemoryClient`.
176 ///
177 /// # Returns
178 /// An `EmailAddress` that is used as the sender's email in the `MemoryClient`.
179 ///
180 /// # Examples
181 ///
182 /// ```rust
183 /// # use email_clients::clients::memory::{MemoryConfig, MemoryClient};
184 /// # use email_clients::traits::EmailTrait;
185 ///
186 /// let config = MemoryConfig::new("sender@example.com");
187 /// let client = MemoryClient::new(config);
188 /// assert_eq!(client.get_sender().to_string(), "sender@example.com");
189 /// ```
190 fn get_sender(&self) -> EmailAddress {
191 self.sender.clone()
192 }
193
194 /// Sends email from memory client.
195 async fn send_emails(&self, email: EmailObject) -> crate::Result<()> {
196 self.tx
197 .send(email)
198 .map_err(|_| EmailError::UnexpectedError("Cannot send email in memory".to_string()))?;
199 Ok(())
200 }
201}