This commit is contained in:
Alexis Mousset
2016-10-23 18:37:19 +02:00
5 changed files with 119 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
//! Represents an Email transport
pub mod smtp;
pub mod sendmail;
pub mod stub;
pub mod file;

View File

@@ -0,0 +1,54 @@
//! Error and result type for sendmail transport
use self::Error::*;
use std::error::Error as StdError;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::io;
/// An enum of all error kinds.
#[derive(Debug)]
pub enum Error {
/// Internal client error
Client(&'static str),
/// IO error
Io(io::Error),
}
impl Display for Error {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
fmt.write_str(self.description())
}
}
impl StdError for Error {
fn description(&self) -> &str {
match *self {
Client(_) => "an unknown error occured",
Io(_) => "an I/O error occured",
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
Io(ref err) => Some(&*err as &StdError),
_ => None,
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Io(err)
}
}
impl From<&'static str> for Error {
fn from(string: &'static str) -> Error {
Client(string)
}
}
/// SendMail result type
pub type SendmailResult = Result<(), Error>;

View File

@@ -0,0 +1,44 @@
//! This transport uilizes the sendmail executable for each email.
use email::SendableEmail;
use std::error::Error;
use std::io::prelude::*;
use std::process::{Command, Stdio};
use transport::EmailTransport;
use transport::sendmail::error::SendmailResult;
pub mod error;
/// Writes the content and the envelope information to a file
pub struct SendmailTransport;
impl EmailTransport<SendmailResult> for SendmailTransport {
fn send<T: SendableEmail>(&mut self, email: T) -> SendmailResult {
// Spawn the `wc` command
let process = try!(Command::new("/usr/sbin/sendmail")
.args(&email.to_addresses())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn());
match process.stdin.unwrap().write_all(email.message().clone().as_bytes()) {
Err(why) => error!("couldn't write to sendmail stdin: {}",
why.description()),
Ok(_) => info!("sent pangram to sendmail"),
}
let mut s = String::new();
match process.stdout.unwrap().read_to_string(&mut s) {
Err(why) => error!("couldn't read sendmail stdout: {}",
why.description()),
Ok(_) => info!("sendmail responded with:\n{}", s),
}
Ok(())
}
fn close(&mut self) {
()
}
}

View File

@@ -1,5 +1,6 @@
extern crate lettre;
mod transport_smtp;
mod transport_sendmail;
mod transport_stub;
mod transport_file;

View File

@@ -0,0 +1,19 @@
extern crate lettre;
use lettre::transport::sendmail::SendmailTransport;
use lettre::transport::EmailTransport;
use lettre::email::EmailBuilder;
#[test]
fn sendmail_transport_simple() {
let mut sender = SendmailTransport;
let email = EmailBuilder::new()
.to("root@localhost")
.from("user@localhost")
.body("Hello World!")
.subject("Hello")
.build()
.unwrap();
let result = sender.send(email);
assert!(result.is_ok());
}