From a4be3c4cd8e17f18afdff3546f22b6ffb0c39c12 Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Sat, 1 May 2021 22:00:33 +0200 Subject: [PATCH] Add InvalidHeaderName error (#608) * Add InvalidHeaderName error --- src/address/types.rs | 6 ++- src/lib.rs | 3 +- src/message/body.rs | 3 ++ src/message/header/content.rs | 6 ++- src/message/header/mailbox.rs | 6 ++- src/message/header/mod.rs | 56 +++++++++++++++++++++------ src/message/header/special.rs | 6 ++- src/transport/smtp/async_transport.rs | 6 ++- 8 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/address/types.rs b/src/address/types.rs index 41407fc..5af8c16 100644 --- a/src/address/types.rs +++ b/src/address/types.rs @@ -224,11 +224,14 @@ impl AsRef for Address { #[derive(Debug, PartialEq, Clone, Copy)] /// Errors in email addresses parsing pub enum AddressError { + /// Missing domain or user MissingParts, + /// Unbalanced angle bracket Unbalanced, + /// Invalid email user InvalidUser, + /// Invalid email domain InvalidDomain, - InvalidUtf8b, } impl Error for AddressError {} @@ -240,7 +243,6 @@ impl Display for AddressError { AddressError::Unbalanced => f.write_str("Unbalanced angle bracket"), AddressError::InvalidUser => f.write_str("Invalid email user"), AddressError::InvalidDomain => f.write_str("Invalid email domain"), - AddressError::InvalidUtf8b => f.write_str("Invalid UTF8b data"), } } } diff --git a/src/lib.rs b/src/lib.rs index dd147dd..c91e7c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -176,8 +176,7 @@ mod test { use std::convert::TryFrom; use super::*; - use crate::message::header::Headers; - use crate::message::{header, Mailbox, Mailboxes}; + use crate::message::{header, header::Headers, Mailbox, Mailboxes}; #[test] fn envelope_from_headers() { diff --git a/src/message/body.rs b/src/message/body.rs index f99d3e7..b973b47 100644 --- a/src/message/body.rs +++ b/src/message/body.rs @@ -19,7 +19,9 @@ pub struct Body { /// makes for a more efficient `Content-Transfer-Encoding` to be chosen. #[derive(Debug, Clone)] pub enum MaybeString { + /// Binary data Binary(Vec), + /// UTF-8 string String(String), } @@ -204,6 +206,7 @@ impl MaybeString { /// **NOTE:** if using the specified `encoding` would result into a malformed /// body, this will panic! pub trait IntoBody { + /// Encode as valid body fn into_body(self, encoding: Option) -> Body; } diff --git a/src/message/header/content.rs b/src/message/header/content.rs index 4e1d3ea..7446207 100644 --- a/src/message/header/content.rs +++ b/src/message/header/content.rs @@ -13,11 +13,15 @@ use crate::BoxError; /// use-caches this header shouldn't be set manually. #[derive(Debug, Clone, Copy, PartialEq)] pub enum ContentTransferEncoding { + /// ASCII SevenBit, + /// Quoted-Printable encoding QuotedPrintable, + /// base64 encoding Base64, - // 8BITMIME + /// Requires `8BITMIME` EightBit, + /// Binary data Binary, } diff --git a/src/message/header/mailbox.rs b/src/message/header/mailbox.rs index bed4170..e43726f 100644 --- a/src/message/header/mailbox.rs +++ b/src/message/header/mailbox.rs @@ -1,6 +1,8 @@ use super::{Header, HeaderName}; -use crate::message::mailbox::{Mailbox, Mailboxes}; -use crate::BoxError; +use crate::{ + message::mailbox::{Mailbox, Mailboxes}, + BoxError, +}; /// Header which can contains multiple mailboxes pub trait MailboxesHeader { diff --git a/src/message/header/mod.rs b/src/message/header/mod.rs index 79fa584..d4cb238 100644 --- a/src/message/header/mod.rs +++ b/src/message/header/mod.rs @@ -2,14 +2,20 @@ use std::{ borrow::Cow, + error::Error, fmt::{self, Display, Formatter}, ops::Deref, }; -pub use self::content_disposition::ContentDisposition; -pub use self::content_type::{ContentType, ContentTypeErr}; -pub use self::date::Date; -pub use self::{content::*, mailbox::*, special::*, textual::*}; +pub use self::{ + content::*, + content_disposition::ContentDisposition, + content_type::{ContentType, ContentTypeErr}, + date::Date, + mailbox::*, + special::*, + textual::*, +}; use crate::BoxError; mod content; @@ -131,22 +137,48 @@ impl Display for Headers { } } +/// A possible error when converting a `HeaderName` from another type. +// comes from `http` crate +#[allow(missing_copy_implementations)] +#[derive(Clone)] +pub struct InvalidHeaderName { + _priv: (), +} + +impl fmt::Debug for InvalidHeaderName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("InvalidHeaderName") + // skip _priv noise + .finish() + } +} + +impl fmt::Display for InvalidHeaderName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("invalid header name") + } +} + +impl Error for InvalidHeaderName {} + #[derive(Debug, Clone)] pub struct HeaderName(Cow<'static, str>); impl HeaderName { - pub fn new_from_ascii(ascii: String) -> Option { + /// Creates a new header name + pub fn new_from_ascii(ascii: String) -> Result { if !ascii.is_empty() && ascii.len() <= 76 && ascii.is_ascii() && !ascii.contains(|c| c == ':' || c == ' ') { - Some(Self(Cow::Owned(ascii))) + Ok(Self(Cow::Owned(ascii))) } else { - None + Err(InvalidHeaderName { _priv: () }) } } + /// Creates a new header name, panics on invalid name pub const fn new_from_ascii_str(ascii: &'static str) -> Self { macro_rules! static_assert { ($condition:expr) => { @@ -482,27 +514,27 @@ mod tests { #[test] fn valid_headername() { - assert!(HeaderName::new_from_ascii(String::from("From")).is_some()); + assert!(HeaderName::new_from_ascii(String::from("From")).is_ok()); } #[test] fn non_ascii_headername() { - assert!(HeaderName::new_from_ascii(String::from("🌎")).is_none()); + assert!(HeaderName::new_from_ascii(String::from("🌎")).is_err()); } #[test] fn spaces_in_headername() { - assert!(HeaderName::new_from_ascii(String::from("From ")).is_none()); + assert!(HeaderName::new_from_ascii(String::from("From ")).is_err()); } #[test] fn colons_in_headername() { - assert!(HeaderName::new_from_ascii(String::from("From:")).is_none()); + assert!(HeaderName::new_from_ascii(String::from("From:")).is_err()); } #[test] fn empty_headername() { - assert!(HeaderName::new_from_ascii(String::from("")).is_none()); + assert!(HeaderName::new_from_ascii(String::from("")).is_err()); } #[test] diff --git a/src/message/header/special.rs b/src/message/header/special.rs index c5c879d..802cb41 100644 --- a/src/message/header/special.rs +++ b/src/message/header/special.rs @@ -1,5 +1,7 @@ -use crate::message::header::{Header, HeaderName}; -use crate::BoxError; +use crate::{ + message::header::{Header, HeaderName}, + BoxError, +}; /// Message format version, defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-4) #[derive(Debug, Copy, Clone, PartialEq)] diff --git a/src/transport/smtp/async_transport.rs b/src/transport/smtp/async_transport.rs index 8895661..b7c40d5 100644 --- a/src/transport/smtp/async_transport.rs +++ b/src/transport/smtp/async_transport.rs @@ -1,5 +1,7 @@ -use std::fmt::{self, Debug}; -use std::marker::PhantomData; +use std::{ + fmt::{self, Debug}, + marker::PhantomData, +}; use async_trait::async_trait;