piknik
piknik copied to clipboard
Add raw header support to MessageBuilder
Is your feature request related to a problem? Please describe.
My project supports configuring the SMTP client through a configuration file: SMTP server, sender mailbox, credentials, etc.
One of the settings is a custom list of extra headers to add to each outbound email. Custom headers are required for some providers but I don't want to hardcode these headers. For example, Postmark requires the X-PM-Message-Stream: outbound
header.
I am now switching our implementation to be based on Lettre but fail to see how to support custom headers that are unknown at compile time (I can impl Header
for a custom struct, but the name needs to be known at compile time).
Describe the solution you'd like
I would like the message builder to provide a method such as .raw_header(name: HeaderName, value: String);
or an API such as .header(RawHeader::new(name, value))
to allow adding headers where the name
is not known at compile-time.
Looking into the code, I feel that it would involve having a cleaner separation between header types and header values (why do I need to implement parse
for headers I intend to only write? It also makes it very complicated to get a dyn Header
). I would also expect this feature to require changes to the Headers
struct, so its API is closer to http:header::HeaderMap
(which serves the same goal).
Describe alternatives you've considered An alternative would be to maintain a predefined list of known headers and handle the conversion from the list of raw headers to the strongly typed known headers myself. This is not desirable because it requires me to restrict the configuration to only known headers while new headers may be required by mail services at any time.
Additional context
I suggest taking inspiration from how the http
crate deals with its headers: it benefited from more work and usage.
Did you find a solution to this issue @paolobarbolini ?
Any plans to implement arbitrary headers? Is there an example how to add custom header to an outgoing email?
Here is an example for an outgoing header:
#[derive(Clone,Debug)]
pub struct ListId<'a>(pub &'a str);
impl<'a> lettre::message::header::Header for ListId<'a> {
fn name() -> lettre::message::header::HeaderName {
lettre::message::header::HeaderName::new_from_ascii_str("List-Id")
}
fn parse(_: &str) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
unimplemented!()
}
fn display(&self) -> lettre::message::header::HeaderValue {
lettre::message::header::HeaderValue::new(
Self::name(),
self.0.into())
}
}