Compare commits

...

2 Commits

Author SHA1 Message Date
Paolo Barbolini
036062a084 Prepare v0.11.18 2025-07-28 09:38:52 +02:00
Francesco Luzzi
8873153178 feat: add ability to give a name to an inline attachment (#1101) 2025-07-21 08:19:31 +02:00
6 changed files with 97 additions and 8 deletions

View File

@@ -1,3 +1,17 @@
<a name="v0.11.18"></a>
### v0.11.18 (2025-07-28)
#### Features
* Allow inline attachments to be named ([#1101])
#### Misc
* Upgrade `socket2` to v0.6 ([#1098])
[#1098]: https://github.com/lettre/lettre/pull/1098
[#1101]: https://github.com/lettre/lettre/pull/1101
<a name="v0.11.17"></a>
### v0.11.17 (2025-06-06)

2
Cargo.lock generated
View File

@@ -1325,7 +1325,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lettre"
version = "0.11.17"
version = "0.11.18"
dependencies = [
"async-std",
"async-trait",

View File

@@ -1,7 +1,7 @@
[package]
name = "lettre"
# remember to update html_root_url and README.md (Cargo.toml example and deps.rs badge)
version = "0.11.17"
version = "0.11.18"
description = "Email client"
readme = "README.md"
homepage = "https://lettre.rs"

View File

@@ -28,8 +28,8 @@
</div>
<div align="center">
<a href="https://deps.rs/crate/lettre/0.11.17">
<img src="https://deps.rs/crate/lettre/0.11.17/status.svg"
<a href="https://deps.rs/crate/lettre/0.11.18">
<img src="https://deps.rs/crate/lettre/0.11.18/status.svg"
alt="dependency status" />
</a>
</div>

View File

@@ -162,7 +162,7 @@
//! [mime 0.3]: https://docs.rs/mime/0.3
//! [DKIM]: https://datatracker.ietf.org/doc/html/rfc6376
#![doc(html_root_url = "https://docs.rs/crate/lettre/0.11.17")]
#![doc(html_root_url = "https://docs.rs/crate/lettre/0.11.18")]
#![doc(html_favicon_url = "https://lettre.rs/favicon.ico")]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/15113230?v=4")]
#![forbid(unsafe_code)]

View File

@@ -16,7 +16,10 @@ enum Disposition {
/// File name
Attached(String),
/// Content id
Inline(String),
Inline {
content_id: String,
name: Option<String>,
},
}
impl Attachment {
@@ -81,7 +84,50 @@ impl Attachment {
/// ```
pub fn new_inline(content_id: String) -> Self {
Attachment {
disposition: Disposition::Inline(content_id),
disposition: Disposition::Inline {
content_id,
name: None,
},
}
}
/// Create a new inline attachment giving it a name
///
/// This attachment should be displayed inline into the message
/// body:
///
/// ```html
/// <img src="cid:123">
/// ```
///
///
/// ```rust
/// # use std::error::Error;
/// use std::fs;
///
/// use lettre::message::{header::ContentType, Attachment};
///
/// # fn main() -> Result<(), Box<dyn Error>> {
/// let content_id = String::from("123");
/// let file_name = String::from("image.jpg");
/// # if false {
/// let filebody = fs::read(&file_name)?;
/// # }
/// # let filebody = fs::read("docs/lettre.png")?;
/// let content_type = ContentType::parse("image/jpeg").unwrap();
/// let attachment =
/// Attachment::new_inline_with_name(content_id, file_name).body(filebody, content_type);
///
/// // The image `attachment` will display inline into the email.
/// # Ok(())
/// # }
/// ```
pub fn new_inline_with_name(content_id: String, name: String) -> Self {
Attachment {
disposition: Disposition::Inline {
content_id,
name: Some(name),
},
}
}
@@ -95,9 +141,18 @@ impl Attachment {
Disposition::Attached(filename) => {
builder.header(header::ContentDisposition::attachment(&filename))
}
Disposition::Inline(content_id) => builder
Disposition::Inline {
content_id,
name: None,
} => builder
.header(header::ContentId::from(format!("<{content_id}>")))
.header(header::ContentDisposition::inline()),
Disposition::Inline {
content_id,
name: Some(name),
} => builder
.header(header::ContentId::from(format!("<{content_id}>")))
.header(header::ContentDisposition::inline_with_name(&name)),
};
builder = builder.header(content_type);
builder.body(content)
@@ -142,4 +197,24 @@ mod tests {
)
);
}
#[test]
fn attachment_inline_with_name() {
let id = String::from("id");
let name = String::from("test");
let part = super::Attachment::new_inline_with_name(id, name).body(
String::from("Hello world!"),
ContentType::parse("text/plain").unwrap(),
);
assert_eq!(
&String::from_utf8_lossy(&part.formatted()),
concat!(
"Content-ID: <id>\r\n",
"Content-Disposition: inline; filename=\"test\"\r\n",
"Content-Type: text/plain\r\n",
"Content-Transfer-Encoding: 7bit\r\n\r\n",
"Hello world!\r\n"
)
);
}
}