Skip to content

Commit

Permalink
fix: strict parsing
Browse files Browse the repository at this point in the history
This is a BREAKING CHANGE in terms of the previous strict parsing behavior. The parsing in EmailAddress::new parses the local_part and domain together as a single address as opposed the previous behavior of parsing those separately. This may lead to mismatch with the previous behavior.

Fixes #4
  • Loading branch information
Sayan751 committed Oct 11, 2021
1 parent f46d18e commit 7df3246
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
3 changes: 2 additions & 1 deletion rust-lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,8 @@ macro_rules! generate_negative_instantiation_test {
#[test]
#[wasm_bindgen_test]
fn $case() {
assert_eq!(EmailAddress::new(&$local_part, &$domain, Some(ParsingOptions::new(true))).is_err(), true);
assert_eq!(EmailAddress::new(&$local_part, &$domain, Some(ParsingOptions::new(false))).is_err(), true);
assert_eq!(EmailAddress::new(&$local_part, &$domain, Some(ParsingOptions::new(true))).is_err(), false);
}
)*
}
Expand Down
45 changes: 26 additions & 19 deletions rust-lib/src/email_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use wasm_bindgen::prelude::*;
/// `true` or `false` to enable/disable obsolete parts parsing.
/// The default is `false`.
#[wasm_bindgen]
#[derive(Debug)]
#[derive(Debug,Clone)]
pub struct ParsingOptions {
pub is_lax: bool,
}
Expand Down Expand Up @@ -86,7 +86,7 @@ impl EmailAddress {
console_error_panic_hook::set_once();
match EmailAddress::new(local_part, domain, options) {
Ok(instance) => instance,
Err(message) => panic!("{}",message),
Err(message) => panic!("{}", message),
}
}

Expand Down Expand Up @@ -255,24 +255,18 @@ impl EmailAddress {
domain: &str,
options: Option<ParsingOptions>,
) -> Result<EmailAddress, String> {
let options = options.unwrap_or_default();
let is_strict = !options.is_lax;

if (is_strict && !RFC5322::parse(Rule::local_part_complete, local_part).is_ok())
|| (!is_strict && !RFC5322::parse(Rule::local_part_complete, local_part).is_ok())
{
return Err(format!("Invalid local part '{}'.", local_part));
}
if (is_strict && !RFC5322::parse(Rule::domain_complete, domain).is_ok())
|| (!is_strict && !RFC5322::parse(Rule::domain_complete, domain).is_ok())
{
return Err(format!("Invalid domain '{}'.", domain));
match EmailAddress::parse(&format!("{}@{}", local_part, domain), options.clone()) {
Some(email_address) => Ok(email_address),
None => {
if !options.unwrap_or_default().is_lax {
return Err(format!("Invalid local part '{}'.", local_part));
}
Ok(EmailAddress {
local_part: String::from(local_part),
domain: String::from(domain),
})
}
}

Ok(EmailAddress {
local_part: String::from(local_part),
domain: String::from(domain),
})
}

/// Returns the local part of the email address.
Expand Down Expand Up @@ -441,4 +435,17 @@ mod tests {
println!("{:#?}", actual);
assert_eq!(actual.is_err(), false);
}

#[test]
fn parsing_empty_local_part_and_domain() {
let actual = EmailAddress::parse("@", Some(ParsingOptions::new(true)));
assert_eq!(actual.is_none(), true, "expected none");
let actual = EmailAddress::new("", "", Some(ParsingOptions::new(false)));
assert_eq!(actual.is_err(), true, "expected error");
let actual = EmailAddress::new("", "", Some(ParsingOptions::new(true)));
assert_eq!(actual.is_ok(), true, "expected ok");
let actual = actual.unwrap();
assert_eq!(actual.domain, "");
assert_eq!(actual.local_part, "");
}
}

0 comments on commit 7df3246

Please sign in to comment.