use std::borrow::Cow;
use std::collections::HashMap;
use std::hash::Hash;
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
struct Attachment<'a> {
name: Cow<'a, str>,
content: Cow<'a, str>,
content_id: Cow<'a, str>,
content_type: Cow<'a, str>,
#[serde(skip_serializing_if = "Option::is_none")]
custom_headers: Option<Vec<CustomHeader<'a>>>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
struct CustomHeader<'a> {
name: Cow<'a, str>,
value: Cow<'a, str>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct Email<'a> {
email_address: Cow<'a, str>,
#[serde(skip_serializing_if = "Option::is_none")]
friendly_name: Option<Cow<'a, str>>,
}
impl<'a> Email<'a> {
pub fn new(email_address: Cow<'a, str>, friendly_name: Option<Cow<'a, str>>) -> Email<'a> {
Email {
email_address: email_address,
friendly_name: friendly_name,
}
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
struct MergeData<'a> {
per_message: Vec<Data<'a>>,
global: Vec<Data<'a>>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
struct Data<'a> {
field: Cow<'a, str>,
value: Cow<'a, str>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct Message<'a> {
to: Vec<Email<'a>>,
from: Email<'a>,
subject: Cow<'a, str>,
text_body: Cow<'a, str>,
#[serde(skip_serializing_if = "Option::is_none")]
html_body: Option<Cow<'a, str>>,
#[serde(skip_serializing_if = "Option::is_none")]
api_template: Option<Cow<'a, str>>,
#[serde(skip_serializing_if = "Option::is_none")]
mailing_id: Option<Cow<'a, str>>,
#[serde(skip_serializing_if = "Option::is_none")]
message_id: Option<Cow<'a, str>>,
#[serde(skip_serializing_if = "Option::is_none")]
charset: Option<Cow<'a, str>>,
#[serde(skip_serializing_if = "Option::is_none")]
custom_headers: Option<Vec<CustomHeader<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
cc: Option<Vec<Email<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
bcc: Option<Vec<Email<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
reply_to: Option<Email<'a>>,
#[serde(skip_serializing_if = "Option::is_none")]
attachment: Option<Vec<Attachment<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
merge_data: Option<MergeData<'a>>,
}
impl<'a> Message<'a> {
pub fn new<T: Into<Cow<'a, str>>>(address: T, name: Option<T>) -> Message<'a> {
let from = match name {
Some(name) => Email::new(address.into(), Some(name.into())),
None => Email::new(address.into(), None),
};
Message {
to: Vec::new(),
from: from,
subject: "".into(),
text_body: "".into(),
html_body: None,
api_template: None,
mailing_id: None,
message_id: None,
charset: None,
custom_headers: None,
cc: None,
bcc: None,
reply_to: None,
attachment: None,
merge_data: None,
}
}
pub fn add_to<T: Into<Cow<'a, str>>>(&mut self, address: T, name: Option<T>) {
match name {
Some(name) => self.to.push(Email::new(address.into(), Some(name.into()))),
None => self.to.push(Email::new(address.into(), None)),
}
}
pub fn set_from<T: Into<Cow<'a, str>>>(&mut self, address: T, name: Option<T>) {
match name {
Some(name) => self.from = Email::new(address.into(), Some(name.into())),
None => self.from = Email::new(address.into(), None),
}
}
pub fn set_subject<T: Into<Cow<'a, str>>>(&mut self, subject: T) {
self.subject = subject.into()
}
pub fn set_text<T: Into<Cow<'a, str>>>(&mut self, text: T) {
self.text_body = text.into()
}
pub fn set_html<T: Into<Cow<'a, str>>>(&mut self, html: T) {
self.html_body = Some(html.into())
}
pub fn set_api_template<T: Into<Cow<'a, str>>>(&mut self, api_template: T) {
self.api_template = Some(api_template.into())
}
pub fn set_message_id<T: Into<Cow<'a, str>>>(&mut self, message_id: T) {
self.message_id = Some(message_id.into())
}
pub fn set_charset<T: Into<Cow<'a, str>>>(&mut self, charset: T) {
self.charset = Some(charset.into())
}
pub fn add_headers<T: Into<Cow<'a, str>> + Eq + Hash>(&mut self, headers: HashMap<T, T>) {
if self.custom_headers.is_none() {
self.custom_headers = Some(Vec::new());
}
if let Some(ref mut custom_headers) = self.custom_headers {
for (name, value) in headers {
custom_headers.push(CustomHeader {
name: name.into(),
value: value.into(),
})
}
}
}
pub fn add_cc<T: Into<Cow<'a, str>>>(&mut self, address: T, name: Option<T>) {
let email = match name {
Some(name) => Email::new(address.into(), Some(name.into())),
None => Email::new(address.into(), None),
};
match self.cc {
Some(ref mut cc) => cc.push(email),
None => self.cc = Some(vec![email]),
}
}
pub fn add_bcc<T: Into<Cow<'a, str>>>(&mut self, address: T, name: Option<T>) {
let email = match name {
Some(name) => Email::new(address.into(), Some(name.into())),
None => Email::new(address.into(), None),
};
match self.bcc {
Some(ref mut bcc) => bcc.push(email),
None => self.bcc = Some(vec![email]),
}
}
pub fn set_reply_to<T: Into<Cow<'a, str>>>(&mut self, address: T, name: Option<T>) {
match name {
Some(name) => self.reply_to = Some(Email::new(address.into(), Some(name.into()))),
None => self.reply_to = Some(Email::new(address.into(), None)),
}
}
}