dust_mail/client/
protocol.rs1use async_trait::async_trait;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use crate::{error::Result, tree::Node};
7
8use super::{
9 connection::ConnectionSecurity,
10 incoming::types::{
11 mailbox::Mailbox,
12 message::{Message, Preview},
13 },
14 outgoing::types::sendable::SendableMessage,
15};
16
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18pub struct RemoteServer {
19 server: String,
20 port: u16,
21 security: ConnectionSecurity,
22}
23
24impl RemoteServer {
25 pub fn new<Server: Into<String>>(
26 server: Server,
27 port: u16,
28 security: ConnectionSecurity,
29 ) -> Self {
30 Self {
31 server: server.into(),
32 port,
33 security,
34 }
35 }
36
37 pub fn security(&self) -> &ConnectionSecurity {
38 &self.security
39 }
40
41 pub fn domain(&self) -> &str {
42 self.server.as_ref()
43 }
44
45 pub fn port(&self) -> u16 {
46 self.port
47 }
48}
49
50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
51pub enum Credentials {
52 Password { username: String, password: String },
53 OAuth { username: String, token: String },
54}
55
56impl Credentials {
57 pub fn username(&self) -> &str {
58 match &self {
59 Credentials::OAuth { username, .. } => username,
60 Credentials::Password { username, .. } => username,
61 }
62 }
63}
64
65impl Credentials {
66 pub fn password<U: Into<String>, P: Into<String>>(username: U, password: P) -> Self {
67 Credentials::Password {
68 username: username.into(),
69 password: password.into(),
70 }
71 }
72
73 pub fn oauth<U: Into<String>, T: Into<String>>(username: U, token: T) -> Self {
74 Credentials::OAuth {
75 username: username.into(),
76 token: token.into(),
77 }
78 }
79}
80
81pub trait ServerCredentials {
82 fn credentials(&self) -> &Credentials;
83}
84
85#[cfg(feature = "smtp")]
86#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
87pub struct SmtpCredentials {
88 server: RemoteServer,
89 credentials: Credentials,
90}
91
92#[cfg(feature = "smtp")]
93impl SmtpCredentials {
94 pub fn new(server: RemoteServer, credentials: Credentials) -> Self {
95 Self {
96 server,
97 credentials,
98 }
99 }
100
101 pub fn server(&self) -> &RemoteServer {
102 &self.server
103 }
104}
105
106#[cfg(feature = "smtp")]
107impl ServerCredentials for SmtpCredentials {
108 fn credentials(&self) -> &Credentials {
109 &self.credentials
110 }
111}
112
113#[cfg(feature = "imap")]
114#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
115pub struct ImapCredentials {
116 server: RemoteServer,
117 credentials: Credentials,
118}
119
120#[cfg(feature = "imap")]
121impl ImapCredentials {
122 pub fn new(server: RemoteServer, credentials: Credentials) -> Self {
123 Self {
124 server,
125 credentials,
126 }
127 }
128
129 pub fn server(&self) -> &RemoteServer {
130 &self.server
131 }
132}
133
134#[cfg(feature = "imap")]
135impl ServerCredentials for ImapCredentials {
136 fn credentials(&self) -> &Credentials {
137 &self.credentials
138 }
139}
140
141#[cfg(feature = "pop")]
142#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
143pub struct PopCredentials {
144 server: RemoteServer,
145 credentials: Credentials,
146}
147
148#[cfg(feature = "pop")]
149impl PopCredentials {
150 pub fn new(server: RemoteServer, credentials: Credentials) -> Self {
151 Self {
152 server,
153 credentials,
154 }
155 }
156
157 pub fn server(&self) -> &RemoteServer {
158 &self.server
159 }
160}
161
162#[cfg(feature = "pop")]
163impl ServerCredentials for PopCredentials {
164 fn credentials(&self) -> &Credentials {
165 &self.credentials
166 }
167}
168
169#[async_trait]
170pub trait IncomingProtocol {
171 async fn send_keep_alive(&mut self) -> Result<()>;
172
173 fn should_keep_alive(&self) -> bool;
174
175 async fn get_mailbox_list(&mut self) -> Result<Node<Mailbox>>;
176
177 async fn get_mailbox(&mut self, mailbox_id: &str) -> Result<Node<Mailbox>>;
178
179 async fn rename_mailbox(&mut self, old_name: &str, new_name: &str) -> Result<()>;
180
181 async fn create_mailbox(&mut self, name: &str) -> Result<()>;
182
183 async fn delete_mailbox(&mut self, box_id: &str) -> Result<()>;
184
185 async fn get_messages(
186 &mut self,
187 box_id: &str,
188 start: usize,
189 end: usize,
190 ) -> Result<Vec<Preview>>;
191
192 async fn get_message(&mut self, box_id: &str, message_id: &str) -> Result<Message>;
193
194 async fn logout(&mut self) -> Result<()>;
195}
196
197#[async_trait]
198pub trait OutgoingProtocol {
199 async fn send_message(&mut self, message: SendableMessage) -> Result<()>;
200}
201
202#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
203pub enum IncomingEmailProtocol {
204 #[cfg(feature = "imap")]
205 Imap(ImapCredentials),
206
207 #[cfg(feature = "pop")]
208 Pop(PopCredentials),
209
210 #[cfg(feature = "maildir")]
211 Maildir(std::path::PathBuf),
212}
213
214#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
215pub enum OutgoingEmailProtocol {
216 #[cfg(feature = "smtp")]
217 Smtp(SmtpCredentials),
218}
219
220pub struct IncomingConfig {}
221
222impl Default for IncomingConfig {
223 fn default() -> Self {
224 let config = Self::new();
225
226 config
227 }
228}
229
230impl IncomingConfig {
231 pub fn new() -> Self {
232 Self {}
233 }
234}