Added is_valid_local_part and is_valid_domain. Also now URI-encode addresses in to_uri.
This commit is contained in:
@@ -53,6 +53,8 @@ assert_eq!(
|
||||
|
||||
* Added UTF-8 support.
|
||||
* Added more test cases, fixing defects in parsing.
|
||||
* Method `to_uri` now supports URI encoding the address as a part of the URI.
|
||||
* Added `is_valid_local_part` and `is_valid_domain` methods.
|
||||
|
||||
**Version 0.1.0**
|
||||
|
||||
@@ -62,6 +64,5 @@ assert_eq!(
|
||||
## TODO
|
||||
|
||||
1. Support comments.
|
||||
1. `to_uri` needs to support URI encoding.
|
||||
1. Support line-feed and whitespace rules.
|
||||
1. Does not parse _into_ `domain-literal` values, only does surface syntax check.
|
||||
|
||||
+62
-6
@@ -31,7 +31,7 @@ assert_eq!(
|
||||
|
||||
assert_eq!(
|
||||
email.to_uri(),
|
||||
"mailto:johnstonsk@gmail.com".to_string()
|
||||
"mailto:johnstonsk%40gmail.com".to_string()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -372,7 +372,7 @@ impl FromStr for EmailAddress {
|
||||
|
||||
impl EmailAddress {
|
||||
///
|
||||
/// Determine whether the passed string is a valid email address. Note this is equivalent to
|
||||
/// Determine whether the `address` string is a valid email address. Note this is equivalent to
|
||||
/// the following:
|
||||
///
|
||||
/// ```rust
|
||||
@@ -383,18 +383,40 @@ impl EmailAddress {
|
||||
/// ```
|
||||
///
|
||||
pub fn is_valid(address: &str) -> bool {
|
||||
Self::from_str(&address).is_ok()
|
||||
Self::from_str(address).is_ok()
|
||||
}
|
||||
|
||||
///
|
||||
/// Return this email address formatted as a URI.
|
||||
/// Determine whether the `part` string would be a valid `local-part` if it were in an
|
||||
/// email address.
|
||||
///
|
||||
pub fn is_valid_local_part(part: &str) -> bool {
|
||||
parse_local_part(part).is_ok()
|
||||
}
|
||||
|
||||
///
|
||||
/// Determine whether the `part` string would be a valid `domain` if it were in an
|
||||
/// email address.
|
||||
///
|
||||
pub fn is_valid_domain(part: &str) -> bool {
|
||||
parse_domain(part).is_ok()
|
||||
}
|
||||
|
||||
///
|
||||
/// Return this email address formatted as a URI. This will also URI-encode the email
|
||||
/// address itself. So, `name@example.org` becomes `mailto:name%40example.org`.
|
||||
///
|
||||
pub fn to_uri(&self) -> String {
|
||||
format!("{}{}", MAILTO_URI_PREFIX, self)
|
||||
let encoded = encode(&self.0);
|
||||
format!("{}{}", MAILTO_URI_PREFIX, encoded)
|
||||
}
|
||||
|
||||
///
|
||||
/// Return a string formatted as a display email with the user name.
|
||||
/// Return a string formatted as a display email with the user name. This is commonly used
|
||||
/// in email headers and other locations where a display name is associated with the
|
||||
/// address.
|
||||
///
|
||||
/// So, `("name@example.org", "My Name")` becomes `"My Name <name@example.org>"`.
|
||||
///
|
||||
pub fn to_display(&self, display_name: &str) -> String {
|
||||
format!("{} <{}>", display_name, self)
|
||||
@@ -405,6 +427,40 @@ impl EmailAddress {
|
||||
// Private Functions
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
fn encode(address: &str) -> String {
|
||||
let mut result = String::new();
|
||||
for c in address.chars() {
|
||||
if is_uri_reserved(c) {
|
||||
result.push_str(&format!("%{:02X}", c as u8))
|
||||
} else {
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn is_uri_reserved(c: char) -> bool {
|
||||
c == '!'
|
||||
|| c == '#'
|
||||
|| c == '$'
|
||||
|| c == '%'
|
||||
|| c == '&'
|
||||
|| c == '\''
|
||||
|| c == '('
|
||||
|| c == ')'
|
||||
|| c == '*'
|
||||
|| c == '+'
|
||||
|| c == ','
|
||||
|| c == '/'
|
||||
|| c == ':'
|
||||
|| c == ';'
|
||||
|| c == '='
|
||||
|| c == '?'
|
||||
|| c == '@'
|
||||
|| c == '['
|
||||
|| c == ']'
|
||||
}
|
||||
|
||||
fn parse_address(address: &str) -> Result<EmailAddress, Error> {
|
||||
let address = if address.starts_with(LT) && address.ends_with(GT) {
|
||||
&address[1..address.len() - 1]
|
||||
|
||||
Reference in New Issue
Block a user