Skip to content

Commit c9948f8

Browse files
feat(attachments): added support for message attachments
1 parent e8493f8 commit c9948f8

File tree

15 files changed

+520
-141
lines changed

15 files changed

+520
-141
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,14 @@ log = "0.4"
6767

6868
validator = "0.16.1"
6969
directories = "5.0.1"
70+
mime = "0.3.17"
7071

7172
[dev-dependencies]
7273
env_logger = "0.10.0"
7374
dotenv = "0.15.0"
7475

7576
[features]
76-
default = [
77-
"pop",
78-
"imap",
79-
"smtp",
80-
"discover",
81-
"runtime-tokio",
82-
"serde",
83-
"maildir",
84-
]
77+
default = ["pop", "imap", "smtp", "discover", "runtime-tokio", "serde", "maildir"]
8578

8679
maildir = ["dep:maildir"]
8780

@@ -97,23 +90,5 @@ imap = ["dep:async-imap"]
9790
serde = ["dep:serde"]
9891
json = ["serde", "dep:serde_json"]
9992

100-
runtime-tokio = [
101-
"dep:tokio",
102-
"async-native-tls/runtime-tokio",
103-
"async-imap?/runtime-tokio",
104-
"async-smtp?/runtime-tokio",
105-
"async-pop?/runtime-tokio",
106-
"autoconfig?/runtime-tokio",
107-
"ms-autodiscover?/runtime-tokio",
108-
"dns-mail-discover?/runtime-tokio",
109-
]
110-
runtime-async-std = [
111-
"dep:async-std",
112-
"async-native-tls/runtime-async-std",
113-
"async-imap?/runtime-async-std",
114-
"async-smtp?/runtime-async-std",
115-
"async-pop?/runtime-async-std",
116-
"autoconfig?/runtime-async-std",
117-
"ms-autodiscover?/runtime-async-std",
118-
"dns-mail-discover?/runtime-async-std",
119-
]
93+
runtime-tokio = ["dep:tokio", "async-native-tls/runtime-tokio", "async-imap?/runtime-tokio", "async-smtp?/runtime-tokio", "async-pop?/runtime-tokio", "autoconfig?/runtime-tokio", "ms-autodiscover?/runtime-tokio", "dns-mail-discover?/runtime-tokio"]
94+
runtime-async-std = ["dep:async-std", "async-native-tls/runtime-async-std", "async-imap?/runtime-async-std", "async-smtp?/runtime-async-std", "async-pop?/runtime-async-std", "autoconfig?/runtime-async-std", "ms-autodiscover?/runtime-async-std", "dns-mail-discover?/runtime-async-std"]

src/client/attachment.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#[cfg(feature = "serde")]
2+
use serde::{Deserialize, Serialize};
3+
4+
#[derive(Debug)]
5+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6+
pub struct Attachment {
7+
id: String,
8+
file_name: Option<String>,
9+
size: usize,
10+
}
11+
12+
impl Attachment {
13+
pub fn new(id: String, file_name: Option<String>, size: usize) -> Self {
14+
Self {
15+
id,
16+
file_name,
17+
size,
18+
}
19+
}
20+
21+
pub fn id(&self) -> &str {
22+
self.id.as_ref()
23+
}
24+
25+
pub fn file_name(&self) -> Option<&String> {
26+
self.file_name.as_ref()
27+
}
28+
29+
pub fn size(&self) -> usize {
30+
self.size
31+
}
32+
}

src/client/builder.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use std::{collections::HashMap, fmt::Display, result};
22

33
use crate::error::{err, Error, ErrorKind, Result};
44

5-
use super::{address::Address, content::Content, incoming::types::flag::Flag, parser, Headers};
5+
use super::{
6+
address::Address, attachment::Attachment, content::Content, incoming::types::flag::Flag,
7+
parser, Headers,
8+
};
69

710
#[derive(Debug)]
811
pub struct MessageBuilder {
@@ -15,6 +18,7 @@ pub struct MessageBuilder {
1518
pub(crate) sent: Option<i64>,
1619
pub(crate) subject: Option<String>,
1720
pub(crate) headers: Option<Headers>,
21+
pub(crate) attachments: Vec<Attachment>,
1822
pub(crate) content: Content,
1923
}
2024

@@ -71,6 +75,7 @@ impl MessageBuilder {
7175
sent: None,
7276
subject: None,
7377
content: Content::default(),
78+
attachments: Vec::new(),
7479
headers: None,
7580
}
7681
}
@@ -127,6 +132,12 @@ impl MessageBuilder {
127132
self
128133
}
129134

135+
pub fn attachments(mut self, attachments: Vec<Attachment>) -> Self {
136+
self.attachments = attachments;
137+
138+
self
139+
}
140+
130141
pub fn subject<S: Display>(mut self, subject: S) -> Self {
131142
self.subject = Some(subject.to_string());
132143

@@ -163,10 +174,14 @@ impl MessageBuilder {
163174
self
164175
}
165176

166-
pub fn build<T: TryFrom<Self>>(self) -> Result<T> {
177+
pub fn build<T: TryFrom<Self, Error = impl Display>>(self) -> Result<T> {
167178
match self.try_into() {
168179
Ok(message) => Ok(message),
169-
Err(_err) => err!(ErrorKind::InvalidMessage, "Could not build a valid message"),
180+
Err(err) => err!(
181+
ErrorKind::InvalidMessage,
182+
"Could not build a valid message: {}",
183+
err
184+
),
170185
}
171186
}
172187
}

0 commit comments

Comments
 (0)