Skip to content

Commit d3d8700

Browse files
committed
v0.1.3
1 parent 1486e3c commit d3d8700

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
mail-builder 0.1.3
2+
================================
3+
- Bug fixes.
4+
- Headers are written sorted alplhabetically.
5+
- Improved ID boundary generation.
6+
- Encoding type detection for `[u8]` text parts.
7+
- Optimised quoted-printable encoding.
8+
19
mail-builder 0.1.2
210
================================
311
- All functions now take `impl Cow<str>`.

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "mail-builder"
33
description = "E-mail builder library for Rust"
4-
version = "0.1.2"
4+
version = "0.1.3"
55
edition = "2018"
66
authors = [ "Stalwart Labs <[email protected]>"]
77
license = "Apache-2.0 OR MIT"

src/mime.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ impl<'x> MimePart<'x> {
224224
let mut boundary: Option<Cow<str>> = None;
225225

226226
loop {
227-
while let Some(part) = it.next() {
227+
while let Some(mut part) = it.next() {
228228
if let Some(boundary) = boundary.as_ref() {
229229
output.write_all(b"\r\n--")?;
230230
output.write_all(boundary.as_bytes())?;
@@ -277,21 +277,45 @@ impl<'x> MimePart<'x> {
277277
stack.push((it, boundary));
278278
}
279279

280-
boundary = Some(make_boundary().into());
281-
282-
for (header_name, mut header_value) in part.headers {
283-
match &mut header_value {
284-
HeaderType::ContentType(ref mut content_type)
285-
if header_name == "Content-Type" =>
286-
{
280+
output.write_all(b"Content-Type: ")?;
281+
boundary = if let Some(value) = part.headers.remove("Content-Type") {
282+
match value {
283+
HeaderType::ContentType(mut ct) => {
287284
if let Entry::Vacant(entry) =
288-
content_type.attributes.entry("boundary".into())
285+
ct.attributes.entry("boundary".into())
289286
{
290-
entry.insert(boundary.as_ref().unwrap().as_ref().into());
287+
entry.insert(make_boundary().into());
288+
}
289+
ct.write_header(&mut output, 14)?;
290+
ct.attributes.remove("boundary")
291+
}
292+
HeaderType::Raw(raw) => {
293+
if let Some(pos) = raw.raw.find("boundary=\"") {
294+
if let Some(boundary) = raw.raw[pos..].split('"').nth(1) {
295+
Some(boundary.to_string().into())
296+
} else {
297+
Some(make_boundary().into())
298+
}
299+
} else {
300+
let boundary = make_boundary();
301+
output.write_all(raw.raw.as_bytes())?;
302+
output.write_all(b"; boundary=\"")?;
303+
output.write_all(boundary.as_bytes())?;
304+
output.write_all(b"\"\r\n")?;
305+
Some(boundary.into())
291306
}
292307
}
293-
_ => {}
308+
_ => panic!("Unsupported Content-Type header value."),
294309
}
310+
} else {
311+
let boundary = make_boundary();
312+
ContentType::new("multipart/mixed")
313+
.attribute("boundary", &boundary)
314+
.write_header(&mut output, 14)?;
315+
Some(boundary.into())
316+
};
317+
318+
for (header_name, header_value) in part.headers {
295319
output.write_all(header_name.as_bytes())?;
296320
output.write_all(b": ")?;
297321
header_value.write_header(&mut output, header_name.len() + 2)?;

0 commit comments

Comments
 (0)