diff options
Diffstat (limited to 'mail/examples/send_mail/main.rs')
-rw-r--r-- | mail/examples/send_mail/main.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/mail/examples/send_mail/main.rs b/mail/examples/send_mail/main.rs new file mode 100644 index 0000000..f00a982 --- /dev/null +++ b/mail/examples/send_mail/main.rs @@ -0,0 +1,114 @@ +//! In this examples runs a simple command line dialog to create a mail +//! and send it to an MSA + +#[cfg(not(feature = "smtp"))] +compile_error!("example `send_mail` requires feature `smtp`"); + +#[macro_use] +extern crate mail; +extern crate rpassword; +extern crate futures; +extern crate tokio; +extern crate soft_ascii_string; + +use std::io::{self, Write}; + +use futures::{Stream, future}; +use soft_ascii_string::SoftAsciiString; + +use mail::{ + Mail, + HeaderTryFrom, + smtp::{ + send_batch as send_mail_batch, + MailRequest, + ConnectionConfig, + ConnectionBuilder, + auth::{Plain as AuthPlain} + }, + error::MailError, + default_impl::simple_context, + header_components::Domain +}; + +mod cli; + +fn main() { + let msg_id_domain = Domain::try_from("company_a.test").unwrap(); + let unique_part = SoftAsciiString::from_string("c207n521cec").unwrap(); + let ctx = simple_context::new(msg_id_domain, unique_part).unwrap(); + let (msa_info, mails) = read_data().unwrap(); + let connection_config = create_connection_config(msa_info); + let mail_requests = create_mail_requests(mails).unwrap(); + + println!("[starting sending mails]"); + + // We run a tokio core "just" for sending the mails, + // normally we probably would schedule/spawn this task + // on a existing tokio runtime. + tokio::run(future::lazy(move || { + send_mail_batch(mail_requests, connection_config, ctx) + .then(|res| Ok(res)) + .for_each(|res| { + match res { + Ok(_) => println!("[mail send]"), + Err(err) => println!("[sending mail failed] {:?}", err) + } + Ok(()) + }) + })); + + println!("[DONE]"); +} + +fn create_connection_config(msa_info: cli::MsaInfo) -> ConnectionConfig<AuthPlain> { + let cli::MsaInfo { domain, auth } = msa_info; + + ConnectionBuilder::new(domain) + .expect("could not resolve domain/host name of MSA") + .auth(AuthPlain::from_username(auth.username, auth.password) + .expect("used \\0 in username or password")) + .build() +} + +fn create_mail_requests(mails: Vec<cli::SimpleMail>) -> Result<Vec<MailRequest>, MailError> { + use mail::headers::*; + + let requests = mails + .into_iter() + .map(|simple_mail| { + let cli::SimpleMail { from, to, subject, text_body } = simple_mail; + let mut mail = Mail::plain_text(text_body); + mail.insert_headers(headers! { + _From: [from], + _To: [to], + Subject: subject + }?); + + Ok(MailRequest::from(mail)) + }) + .collect::<Result<Vec<_>,_>>(); + + requests +} + + + +fn read_data() -> Result<(cli::MsaInfo, Vec<cli::SimpleMail>), io::Error> { + cli::with_dialog(|mut dialog| { + let msa_info = dialog.read_msa_info()?; + let mut mails = Vec::new(); + let mut more = true; + + writeln!(dialog.stdout(), "\nreading mails:")?; + while more { + let mail = dialog.read_simple_mail()?; + mails.push(mail); + dialog.prompt("Another Mail? [y/n]")?; + more = dialog.read_yn()?; + } + writeln!(dialog.stdout(), "[collecting data done]")?; + Ok((msa_info, mails)) + }) +} + |