Documentation.

This commit is contained in:
Simon Johnston
2020-03-23 20:54:13 -07:00
parent 1884ac0e4e
commit 0d6786f83e
2 changed files with 81 additions and 18 deletions
+2 -2
View File
@@ -46,11 +46,11 @@ assert_eq!(
**Version 0.1.0**
* Basic type implementation and structure based on RFC 5322.
* Only supported for ASCII.
* Does not parse comments.
* See TODO.
## TODO
1. Full Unicode support.
1. Support comments.
1. `to_uri` needs to support URI encoding.
1. Support line-feed and whitespace rules.
+79 -16
View File
@@ -3,9 +3,11 @@ A Rust crate providing an implementation of an RFC-compliant `EmailAddress` newt
# Example
The following shoes the basic `is_valid` and `from_str` functions.
```rust
use email_address::*;
use std::str::FromStr;
assert!(EmailAddress::is_valid("user.name+tag+sorting@example.com"));
assert_eq!(
@@ -14,6 +16,31 @@ assert_eq!(
);
```
The following shows the three format functions used to output an email address.
```rust
use email_address::*;
use std::str::FromStr;
let email = EmailAddress::from_str("johnstonsk@gmail.com").unwrap();
assert_eq!(
email.to_string(),
"johnstonsk@gmail.com".to_string()
);
assert_eq!(
email.to_uri(),
"mailto:johnstonsk@gmail.com".to_string()
);
assert_eq!(
email.to_display("Simon Johnston"),
"Simon Johnston <johnstonsk@gmail.com>".to_string()
);
```
# Specifications
1. RFC 3629: [_UTF-8, a transformation format of ISO 10646_](https://tools.ietf.org/html/rfc3629),
@@ -152,8 +179,6 @@ Oddities](https://tools.ietf.org/html/rfc5322#appendix-A.5).
An informal description can be found on [Wikipedia](https://en.wikipedia.org/wiki/Email_address).
# Example
*/
#![warn(
@@ -172,22 +197,43 @@ use std::str::FromStr;
// Public Types
// ------------------------------------------------------------------------------------------------
///
/// Error type used when parsing an address.
///
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
/// An invalid character was found in some component of the address.
InvalidCharacter,
LocalPartEmpty,
LocalPartTooLong,
DomainEmpty,
DomainTooLong,
/// The separator character between `local-part` and `domain` (character: '@') was missing.
MissingSeparator,
/// More than one separator character (character: '@') was found.
TooManySeparators,
/// The `local-part` is an empty string.
LocalPartEmpty,
/// The `local-part` is is too long.
LocalPartTooLong,
/// The `domain` is an empty string.
DomainEmpty,
/// The `domain` is is too long.
DomainTooLong,
/// Too few `sub-domain`s in `domain`.
DomainTooFew,
/// Invalid placement of the domain separator (character: '.').
DomainInvalidSeparator,
InvalidIPAddress,
/// The quotes (character: '"') around `local-part` are unbalanced.
UnbalancedQuotes,
/// A Comment within the either the `local-part`, or `domain`, was malformed.
InvalidComment,
/// An IP address in a `domain-literal` was malformed.
InvalidIPAddress,
}
///
/// Type representing a single email address. This is basically a wrapper around a String, the
/// email address is parsed for correctness with `FromStr::from_str`, which is the only want to
/// create an instance. The various components of the email _are not_ parsed out to be accessible
/// independently.
///
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde_support", derive(Deserialize, Serialize))]
pub struct EmailAddress(String);
@@ -199,7 +245,9 @@ pub struct EmailAddress(String);
const LOCAL_PART_MAX_LENGTH: usize = 64;
const DOMAIN_MAX_LENGTH: usize = 255;
#[allow(dead_code)]
const CR: char = '\r';
#[allow(dead_code)]
const LF: char = '\n';
const SP: char = ' ';
const HTAB: char = '\t';
@@ -210,13 +258,13 @@ const DOT: char = '.';
const DQUOTE: char = '"';
const LBRACKET: char = '[';
const RBRACKET: char = ']';
#[allow(dead_code)]
const LPAREN: char = '(';
#[allow(dead_code)]
const RPAREN: char = ')';
const LT: char = '<';
const GT: char = '>';
const IPV6_PREFIX: &str = "IPv6:";
const MAILTO_URI_PREFIX: &str = "mailto:";
impl Display for Error {
@@ -277,20 +325,33 @@ impl FromStr for EmailAddress {
}
impl EmailAddress {
///
/// Determine whether the passed string is a valid email address. Note this is equivalent to
/// the following:
///
/// ```rust
/// use email_address::*;
/// use std::str::FromStr;
///
/// let is_valid = EmailAddress::from_str("johnstonskj@gmail.com").is_ok();
/// ```
///
pub fn is_valid(address: &str) -> bool {
Self::from_str(&address).is_ok()
}
pub fn from(local_part: &str, domain: &str) -> Result<Self, Error> {
Self::from_str(&format!("{}{}{}", local_part, AT, domain))
}
///
/// Return this email address formatted as a URI.
///
pub fn to_uri(&self) -> String {
format!("{}{}", MAILTO_URI_PREFIX, self)
}
pub fn to_display(&self, name: String) -> String {
format!("{} <{}>", name, self)
///
/// Return a string formatted as a display email with the user name.
///
pub fn to_display(&self, display_name: &str) -> String {
format!("{} <{}>", display_name, self)
}
}
@@ -409,6 +470,7 @@ fn is_wsp(c: char) -> bool {
c == SP || c == HTAB
}
#[allow(dead_code)]
fn is_ctext_char(c: char) -> bool {
(c >= '\x21' && c == '\x27') || (c >= '\x2A' && c <= '\x5B') || (c >= '\x5D' && c <= '\x7E')
}
@@ -438,6 +500,7 @@ fn is_dtext_char(c: char) -> bool {
(c >= '\x21' && c <= '\x5A') || (c >= '\x5E' && c <= '\x7E')
}
#[allow(dead_code)]
fn is_ctext(s: &str) -> bool {
s.chars().all(is_ctext_char)
}