Move the actual logic of email parsing to EmailAddress::new() (#3656)

Very small PR; Motivation: Easier navigation using Go-To-definition.

Because, using go-to-definition of rust-analyzer on parse() doesn't take you to the actual parse() implementation but its trait definiton. On the other hand, it's very easy to find EmailAddress::new().
This commit is contained in:
Hocuri
2022-10-12 20:37:17 +02:00
committed by GitHub
parent 7ed947f598
commit 0e2445c7a0
6 changed files with 28 additions and 29 deletions

View File

@@ -196,7 +196,7 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
}
// no oauth? - just continue it's no error
let parsed: EmailAddress = param.addr.parse().context("Bad email-address")?;
let parsed = EmailAddress::new(&param.addr).context("Bad email-address")?;
let param_domain = parsed.domain;
let param_addr_urlencoded = utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();

View File

@@ -1183,7 +1183,7 @@ impl Contact {
/// Returns false if addr is an invalid address, otherwise true.
pub fn may_be_valid_addr(addr: &str) -> bool {
let res = addr.parse::<EmailAddress>();
let res = EmailAddress::new(addr);
res.is_ok()
}

View File

@@ -693,6 +693,7 @@ mod tests {
use crate::peerstate::Peerstate;
use crate::receive_imf::receive_imf;
use crate::test_utils::{TestContext, TestContextManager};
use crate::tools::EmailAddress;
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_setup_contact() {
@@ -722,7 +723,10 @@ mod tests {
);
let sent = bob.pop_sent_msg().await;
assert_eq!(sent.recipient(), "alice@example.org".parse().unwrap());
assert_eq!(
sent.recipient(),
EmailAddress::new("alice@example.org").unwrap()
);
let msg = alice.parse_msg(&sent).await;
assert!(!msg.was_encrypted());
assert_eq!(msg.get_header(HeaderDef::SecureJoin).unwrap(), "vc-request");
@@ -1087,7 +1091,10 @@ mod tests {
assert_eq!(Chatlist::try_load(&bob, 0, None, None).await?.len(), 1);
let sent = bob.pop_sent_msg().await;
assert_eq!(sent.recipient(), "alice@example.org".parse().unwrap());
assert_eq!(
sent.recipient(),
EmailAddress::new("alice@example.org").unwrap()
);
let msg = alice.parse_msg(&sent).await;
assert!(!msg.was_encrypted());
assert_eq!(msg.get_header(HeaderDef::SecureJoin).unwrap(), "vg-request");

View File

@@ -396,7 +396,7 @@ UPDATE chats SET protected=1, type=120 WHERE type=130;"#,
if dbversion < 71 {
info!(context, "[migration] v71");
if let Ok(addr) = context.get_primary_self_addr().await {
if let Ok(domain) = addr.parse::<EmailAddress>().map(|email| email.domain) {
if let Ok(domain) = EmailAddress::new(&addr).map(|email| email.domain) {
context
.set_config(
Config::ConfiguredProvider,

View File

@@ -740,7 +740,7 @@ impl SentMessage {
.split(' ')
.next()
.expect("no recipient found");
rcpt.parse().expect("failed to parse email address")
EmailAddress::new(rcpt).expect("failed to parse email address")
}
/// The raw message payload.

View File

@@ -7,7 +7,7 @@ use std::fmt;
use std::io::Cursor;
use std::path::{Path, PathBuf};
use std::str::from_utf8;
use std::str::FromStr;
use std::time::{Duration, SystemTime};
use anyhow::{bail, Error, Result};
@@ -524,23 +524,15 @@ pub struct EmailAddress {
pub domain: String,
}
impl EmailAddress {
pub fn new(input: &str) -> Result<Self> {
input.parse::<EmailAddress>()
}
}
impl fmt::Display for EmailAddress {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}@{}", self.local, self.domain)
}
}
impl FromStr for EmailAddress {
type Err = Error;
impl EmailAddress {
/// Performs a dead-simple parse of an email address.
fn from_str(input: &str) -> Result<EmailAddress> {
pub fn new(input: &str) -> Result<EmailAddress> {
if input.is_empty() {
bail!("empty string is not valid");
}
@@ -945,36 +937,36 @@ Hop: From: hq5.example.org; By: hq5.example.org; Date: Mon, 27 Dec 2021 11:21:22
#[test]
fn test_emailaddress_parse() {
assert_eq!("".parse::<EmailAddress>().is_ok(), false);
assert_eq!(EmailAddress::new("").is_ok(), false);
assert_eq!(
"user@domain.tld".parse::<EmailAddress>().unwrap(),
EmailAddress::new("user@domain.tld").unwrap(),
EmailAddress {
local: "user".into(),
domain: "domain.tld".into(),
}
);
assert_eq!(
"user@localhost".parse::<EmailAddress>().unwrap(),
EmailAddress::new("user@localhost").unwrap(),
EmailAddress {
local: "user".into(),
domain: "localhost".into()
}
);
assert_eq!("uuu".parse::<EmailAddress>().is_ok(), false);
assert_eq!("dd.tt".parse::<EmailAddress>().is_ok(), false);
assert!("tt.dd@uu".parse::<EmailAddress>().is_ok());
assert!("u@d".parse::<EmailAddress>().is_ok());
assert!("u@d.".parse::<EmailAddress>().is_ok());
assert!("u@d.t".parse::<EmailAddress>().is_ok());
assert_eq!(EmailAddress::new("uuu").is_ok(), false);
assert_eq!(EmailAddress::new("dd.tt").is_ok(), false);
assert!(EmailAddress::new("tt.dd@uu").is_ok());
assert!(EmailAddress::new("u@d").is_ok());
assert!(EmailAddress::new("u@d.").is_ok());
assert!(EmailAddress::new("u@d.t").is_ok());
assert_eq!(
"u@d.tt".parse::<EmailAddress>().unwrap(),
EmailAddress::new("u@d.tt").unwrap(),
EmailAddress {
local: "u".into(),
domain: "d.tt".into(),
}
);
assert!("u@tt".parse::<EmailAddress>().is_ok());
assert_eq!("@d.tt".parse::<EmailAddress>().is_ok(), false);
assert!(EmailAddress::new("u@tt").is_ok());
assert_eq!(EmailAddress::new("@d.tt").is_ok(), false);
}
use crate::chatlist::Chatlist;