Add InvalidHeaderName error (#608)

* Add InvalidHeaderName error
This commit is contained in:
Alexis Mousset
2021-05-01 22:00:33 +02:00
committed by GitHub
parent 4586f2ad8a
commit a4be3c4cd8
8 changed files with 69 additions and 23 deletions

View File

@@ -224,11 +224,14 @@ impl AsRef<OsStr> 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"),
}
}
}

View File

@@ -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() {

View File

@@ -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<u8>),
/// 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<ContentTransferEncoding>) -> Body;
}

View File

@@ -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,
}

View File

@@ -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 {

View File

@@ -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<Self> {
/// Creates a new header name
pub fn new_from_ascii(ascii: String) -> Result<Self, InvalidHeaderName> {
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]

View File

@@ -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)]

View File

@@ -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;