Remove failure crate usage (fixes #331)

This commit is contained in:
Alexis Mousset
2019-03-23 12:04:39 +01:00
parent 101189882a
commit cabc625009
9 changed files with 139 additions and 71 deletions

View File

@@ -28,8 +28,6 @@ hostname = { version = "^0.1", optional = true }
serde = { version = "^1.0", optional = true } serde = { version = "^1.0", optional = true }
serde_json = { version = "^1.0", optional = true } serde_json = { version = "^1.0", optional = true }
serde_derive = { version = "^1.0", optional = true } serde_derive = { version = "^1.0", optional = true }
failure = "^0.1"
failure_derive = "^0.1"
fast_chemail = "^0.9" fast_chemail = "^0.9"
r2d2 = { version = "^0.8", optional = true} r2d2 = { version = "^0.8", optional = true}

View File

@@ -1,18 +1,35 @@
use failure; use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use self::Error::*;
/// Error type for email content /// Error type for email content
#[derive(Fail, Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Error { pub enum Error {
/// Missing from in envelope /// Missing from in envelope
#[fail(display = "missing source address, invalid envelope")]
MissingFrom, MissingFrom,
/// Missing to in envelope /// Missing to in envelope
#[fail(display = "missing destination address, invalid envelope")]
MissingTo, MissingTo,
/// Invalid email /// Invalid email
#[fail(display = "invalid email address")]
InvalidEmailAddress, InvalidEmailAddress,
} }
impl Display for Error {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
fmt.write_str(&match *self {
MissingFrom => "missing source address, invalid envelope".to_owned(),
MissingTo => "missing destination address, invalid envelope".to_owned(),
InvalidEmailAddress => "invalid email address".to_owned(),
})
}
}
impl StdError for Error {
fn cause(&self) -> Option<&dyn StdError> {
None
}
}
/// Email result type /// Email result type
pub type EmailResult<T> = Result<T, failure::Error>; pub type EmailResult<T> = Result<T, Error>;

View File

@@ -1,40 +1,65 @@
//! Error and result type for file transport //! Error and result type for file transport
use failure; use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use serde_json; use serde_json;
use std::io; use std::io;
use self::Error::*;
/// An enum of all error kinds. /// An enum of all error kinds.
#[derive(Fail, Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
/// Internal client error /// Internal client error
#[fail(display = "Internal client error: {}", error)] Client(&'static str),
Client { error: &'static str },
/// IO error /// IO error
#[fail(display = "IO error: {}", error)] Io(io::Error),
Io { error: io::Error },
/// JSON serialization error /// JSON serialization error
#[fail(display = "JSON serialization error: {}", error)] JsonSerialization(serde_json::Error),
JsonSerialization { error: serde_json::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(err) => err,
Io(ref err) => err.description(),
JsonSerialization(ref err) => err.description(),
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
Io(ref err) => Some(&*err),
JsonSerialization(ref err) => Some(&*err),
_ => None,
}
}
} }
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(err: io::Error) -> Error { fn from(err: io::Error) -> Error {
Error::Io { error: err } Error::Io(err)
} }
} }
impl From<serde_json::Error> for Error { impl From<serde_json::Error> for Error {
fn from(err: serde_json::Error) -> Error { fn from(err: serde_json::Error) -> Error {
Error::JsonSerialization { error: err } Error::JsonSerialization(err)
} }
} }
impl From<&'static str> for Error { impl From<&'static str> for Error {
fn from(string: &'static str) -> Error { fn from(string: &'static str) -> Error {
Error::Client { error: string } Error::Client(string)
} }
} }
/// SMTP result type /// SMTP result type
pub type FileResult = Result<(), failure::Error>; pub type FileResult = Result<(), Error>;

View File

@@ -30,11 +30,8 @@ extern crate serde;
#[cfg(feature = "serde-impls")] #[cfg(feature = "serde-impls")]
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate failure;
#[cfg(feature = "file-transport")] #[cfg(feature = "file-transport")]
extern crate serde_json; extern crate serde_json;
#[macro_use]
extern crate failure_derive;
extern crate fast_chemail; extern crate fast_chemail;
#[cfg(feature = "connection-pool")] #[cfg(feature = "connection-pool")]
extern crate r2d2; extern crate r2d2;
@@ -49,8 +46,7 @@ pub mod smtp;
pub mod stub; pub mod stub;
use error::EmailResult; use error::EmailResult;
use error::Error as EmailError; use error::Error;
use failure::Error;
use fast_chemail::is_valid_email; use fast_chemail::is_valid_email;
#[cfg(feature = "file-transport")] #[cfg(feature = "file-transport")]
pub use file::FileTransport; pub use file::FileTransport;
@@ -77,7 +73,7 @@ pub struct EmailAddress(String);
impl EmailAddress { impl EmailAddress {
pub fn new(address: String) -> EmailResult<EmailAddress> { pub fn new(address: String) -> EmailResult<EmailAddress> {
if !is_valid_email(&address) && !address.ends_with("localhost") { if !is_valid_email(&address) && !address.ends_with("localhost") {
Err(EmailError::InvalidEmailAddress)?; Err(Error::InvalidEmailAddress)?;
} }
Ok(EmailAddress(address)) Ok(EmailAddress(address))
} }
@@ -127,7 +123,7 @@ impl Envelope {
/// Creates a new envelope, which may fail if `to` is empty. /// Creates a new envelope, which may fail if `to` is empty.
pub fn new(from: Option<EmailAddress>, to: Vec<EmailAddress>) -> EmailResult<Envelope> { pub fn new(from: Option<EmailAddress>, to: Vec<EmailAddress>) -> EmailResult<Envelope> {
if to.is_empty() { if to.is_empty() {
Err(EmailError::MissingTo)?; Err(Error::MissingTo)?;
} }
Ok(Envelope { Ok(Envelope {
forward_path: to, forward_path: to,

View File

@@ -1,30 +1,54 @@
//! Error and result type for sendmail transport //! Error and result type for sendmail transport
use failure; use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use self::Error::*;
use std::io; use std::io;
/// An enum of all error kinds. /// An enum of all error kinds.
#[derive(Fail, Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
/// Internal client error /// Internal client error
#[fail(display = "Internal client error: {}", error)] Client(&'static str),
Client { error: &'static str },
/// IO error /// IO error
#[fail(display = "IO error: {}", error)] Io(io::Error),
Io { error: 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(err) => err,
Io(ref err) => err.description(),
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
Io(ref err) => Some(&*err),
_ => None,
}
}
} }
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(err: io::Error) -> Error { fn from(err: io::Error) -> Error {
Error::Io { error: err } Error::Io(err)
} }
} }
impl From<&'static str> for Error { impl From<&'static str> for Error {
fn from(string: &'static str) -> Error { fn from(string: &'static str) -> Error {
Error::Client { error: string } Error::Client(string)
} }
} }
/// sendmail result type /// sendmail result type
pub type SendmailResult = Result<(), failure::Error>; pub type SendmailResult = Result<(), Error>;

View File

@@ -72,9 +72,7 @@ impl<'a> Transport<'a> for SendmailTransport {
Ok(()) Ok(())
} else { } else {
// TODO display stderr // TODO display stderr
Err(error::Error::Client { Err(error::Error::Client("The message could not be sent"))?
error: "The message could not be sent",
})?
} }
} }
} }

View File

@@ -29,5 +29,3 @@ time = "^0.1"
uuid = { version = "^0.7", features = ["v4"] } uuid = { version = "^0.7", features = ["v4"] }
lettre = { version = "^0.9", path = "../lettre", default-features = false } lettre = { version = "^0.9", path = "../lettre", default-features = false }
base64 = "^0.10" base64 = "^0.10"
failure = "^0.1"
failure_derive = "^0.1"

View File

@@ -2,35 +2,52 @@
use lettre; use lettre;
use std::io; use std::io;
use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use self::Error::*;
/// An enum of all error kinds. /// An enum of all error kinds.
#[derive(Debug, Fail)] #[derive(Debug)]
pub enum Error { pub enum Error {
/// Envelope error /// Envelope error
#[fail(display = "lettre error: {}", error)] Envelope(lettre::error::Error),
Envelope {
/// inner error
error: lettre::error::Error,
},
/// Unparseable filename for attachment /// Unparseable filename for attachment
#[fail(display = "the attachment filename could not be parsed")]
CannotParseFilename, CannotParseFilename,
/// IO error /// IO error
#[fail(display = "IO error: {}", error)] Io(io::Error),
Io { }
/// inner error
error: io::Error, impl Display for Error {
}, fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
fmt.write_str(&match *self {
CannotParseFilename => "Could not parse attachment filename".to_owned(),
Io(ref err) => err.to_string(),
Envelope(ref err) => err.to_string(),
})
}
}
impl StdError for Error {
fn cause(&self) -> Option<&dyn StdError> {
match *self {
Envelope(ref err) => Some(err),
Io(ref err) => Some(err),
_ => None,
}
}
} }
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(err: io::Error) -> Error { fn from(err: io::Error) -> Error {
Error::Io { error: err } Error::Io(err)
} }
} }
impl From<lettre::error::Error> for Error { impl From<lettre::error::Error> for Error {
fn from(err: lettre::error::Error) -> Error { fn from(err: lettre::error::Error) -> Error {
Error::Envelope { error: err } Error::Envelope(err)
} }
} }

View File

@@ -13,10 +13,6 @@
unused_import_braces unused_import_braces
)] )]
extern crate failure;
#[macro_use]
extern crate failure_derive;
extern crate base64; extern crate base64;
extern crate email as email_format; extern crate email as email_format;
extern crate lettre; extern crate lettre;
@@ -27,8 +23,7 @@ extern crate uuid;
pub mod error; pub mod error;
pub use email_format::{Address, Header, Mailbox, MimeMessage, MimeMultipartType}; pub use email_format::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
use error::Error as EmailError; use error::Error;
use failure::Error;
use lettre::{error::Error as LettreError, EmailAddress, Envelope, SendableEmail}; use lettre::{error::Error as LettreError, EmailAddress, Envelope, SendableEmail};
use mime::Mime; use mime::Mime;
use std::fs; use std::fs;
@@ -263,7 +258,7 @@ impl EmailBuilder {
filename.unwrap_or( filename.unwrap_or(
path.file_name() path.file_name()
.and_then(|x| x.to_str()) .and_then(|x| x.to_str())
.ok_or(EmailError::CannotParseFilename)?, .ok_or(Error::CannotParseFilename)?,
), ),
content_type, content_type,
) )
@@ -416,15 +411,15 @@ impl EmailBuilder {
// if it's an author group, use the first author // if it's an author group, use the first author
Some(mailbox) => Ok(mailbox.address.clone()), Some(mailbox) => Ok(mailbox.address.clone()),
// for an empty author group (the rarest of the rare cases) // for an empty author group (the rarest of the rare cases)
None => Err(EmailError::Envelope { None => Err(Error::Envelope(
error: LettreError::MissingFrom, LettreError::MissingFrom,
}), // empty envelope sender )), // empty envelope sender
}, },
}, },
// if we don't have a from header // if we don't have a from header
None => Err(EmailError::Envelope { None => Err(Error::Envelope(
error: LettreError::MissingFrom, LettreError::MissingFrom,
}), // empty envelope sender )), // empty envelope sender
} }
} }
}?)?); }?)?);
@@ -448,9 +443,9 @@ impl EmailBuilder {
.message .message
.header(Header::new_with_value("From".into(), from).unwrap()); .header(Header::new_with_value("From".into(), from).unwrap());
} else { } else {
Err(EmailError::Envelope { Err(Error::Envelope(
error: LettreError::MissingFrom, LettreError::MissingFrom,
})?; ))?;
} }
if !self.cc.is_empty() { if !self.cc.is_empty() {
self.message = self self.message = self