use async_trait::async_trait;
use eternaltwin_core::core::LocaleId;
use eternaltwin_core::email::{EmailBody, EmailContent, EmailFormatter, EmailSubject, VerifyRegistrationEmail};
use eternaltwin_core::forum::MarktwinText;
use eternaltwin_core::types::WeakError;
use marktwin::emitter::emit_html;
use marktwin::grammar::Grammar;
use std::str::FromStr;
pub struct HtmlEmailFormatter;
#[async_trait]
impl EmailFormatter for HtmlEmailFormatter {
async fn verify_registration_email(
&self,
locale: LocaleId,
data: &VerifyRegistrationEmail,
) -> Result<EmailContent, WeakError> {
let registration_uri = format!(
"https://eternaltwin.org/register/verified-email?token={}",
data.token.as_str()
);
let content = match locale {
LocaleId::FrFr => EmailContent {
subject: "Inscription à Eternaltwin".parse().unwrap(),
body_text: format!(
"Bienvenue sur Eternaltwin !\nVeuillez cliquez sur le lien suivant pour valider votre inscription : {}\n",
registration_uri
)
.parse()
.unwrap(),
body_html: None,
},
_ => EmailContent {
subject: "Eternaltwin registration".parse().unwrap(),
body_text: format!(
"Welcome to Eternaltwin!\nPlease click on the following link to complete your registration: {}\n",
registration_uri
)
.parse()
.unwrap(),
body_html: None,
},
};
Ok(content)
}
async fn marktwin(&self, subject: EmailSubject, data: &MarktwinText) -> Result<EmailContent, WeakError> {
let grammar = Grammar::full();
let body = marktwin::parser::parse(&grammar, data.as_str());
let body =
marktwin::ast::concrete::Root::try_from(body.syntax()).map_err(|()| WeakError::new("malformed input"))?;
let text = EmailBody::from_str(data.as_str()).map_err(WeakError::wrap)?;
let html = {
let mut bytes: Vec<u8> = Vec::new();
emit_html(&mut bytes, &body).map_err(WeakError::wrap)?;
String::from_utf8(bytes).map_err(WeakError::wrap)?
};
Ok(EmailContent {
subject,
body_text: text,
body_html: Some(html),
})
}
}
#[cfg(test)]
mod test {
use crate::html::HtmlEmailFormatter;
use eternaltwin_core::core::LocaleId;
use eternaltwin_core::email::{EmailContent, EmailFormatter, VerifyRegistrationEmail};
#[tokio::test]
async fn verify_registration_en() {
let formatter = HtmlEmailFormatter;
let actual = formatter
.verify_registration_email(
LocaleId::EnUs,
&VerifyRegistrationEmail {
token: "abcdef".to_string(),
},
)
.await
.unwrap();
let expected = EmailContent {
subject: "Eternaltwin registration".parse().unwrap(),
body_text: r#"Welcome to Eternaltwin!
Please click on the following link to complete your registration: https://eternaltwin.org/register/verified-email?token=abcdef
"#
.parse()
.unwrap(),
body_html: None,
};
assert_eq!(actual, expected);
}
#[tokio::test]
async fn verify_registration_fr() {
let formatter = HtmlEmailFormatter;
let actual = formatter
.verify_registration_email(
LocaleId::FrFr,
&VerifyRegistrationEmail {
token: "abcdef".to_string(),
},
)
.await
.unwrap();
let expected = EmailContent {
subject: "Inscription à Eternaltwin".parse().unwrap(),
body_text: r#"Bienvenue sur Eternaltwin !
Veuillez cliquez sur le lien suivant pour valider votre inscription : https://eternaltwin.org/register/verified-email?token=abcdef
"#
.parse()
.unwrap(),
body_html: None,
};
assert_eq!(actual, expected);
}
}