From 0e2445c7a07e7b7ad05f0b0f3ff2e558387c7f38 Mon Sep 17 00:00:00 2001 From: Hocuri Date: Wed, 12 Oct 2022 20:37:17 +0200 Subject: [PATCH] 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(). --- src/configure.rs | 2 +- src/contact.rs | 2 +- src/securejoin.rs | 11 +++++++++-- src/sql/migrations.rs | 2 +- src/test_utils.rs | 2 +- src/tools.rs | 38 +++++++++++++++----------------------- 6 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/configure.rs b/src/configure.rs index 33447db18..f61c45fed 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -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(¶m.addr).context("Bad email-address")?; let param_domain = parsed.domain; let param_addr_urlencoded = utf8_percent_encode(¶m.addr, NON_ALPHANUMERIC).to_string(); diff --git a/src/contact.rs b/src/contact.rs index f2c1ba5fc..0d9af4a4c 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -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::(); + let res = EmailAddress::new(addr); res.is_ok() } diff --git a/src/securejoin.rs b/src/securejoin.rs index 75b0ccbe0..81d0bd78d 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -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"); diff --git a/src/sql/migrations.rs b/src/sql/migrations.rs index 2d4f43fd7..6b1f6aae1 100644 --- a/src/sql/migrations.rs +++ b/src/sql/migrations.rs @@ -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::().map(|email| email.domain) { + if let Ok(domain) = EmailAddress::new(&addr).map(|email| email.domain) { context .set_config( Config::ConfiguredProvider, diff --git a/src/test_utils.rs b/src/test_utils.rs index 6ab5ea19f..9f9e456a0 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -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. diff --git a/src/tools.rs b/src/tools.rs index f511c9370..447d48934 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -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 { - input.parse::() - } -} - 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 { + pub fn new(input: &str) -> Result { 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::().is_ok(), false); + assert_eq!(EmailAddress::new("").is_ok(), false); assert_eq!( - "user@domain.tld".parse::().unwrap(), + EmailAddress::new("user@domain.tld").unwrap(), EmailAddress { local: "user".into(), domain: "domain.tld".into(), } ); assert_eq!( - "user@localhost".parse::().unwrap(), + EmailAddress::new("user@localhost").unwrap(), EmailAddress { local: "user".into(), domain: "localhost".into() } ); - assert_eq!("uuu".parse::().is_ok(), false); - assert_eq!("dd.tt".parse::().is_ok(), false); - assert!("tt.dd@uu".parse::().is_ok()); - assert!("u@d".parse::().is_ok()); - assert!("u@d.".parse::().is_ok()); - assert!("u@d.t".parse::().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::().unwrap(), + EmailAddress::new("u@d.tt").unwrap(), EmailAddress { local: "u".into(), domain: "d.tt".into(), } ); - assert!("u@tt".parse::().is_ok()); - assert_eq!("@d.tt".parse::().is_ok(), false); + assert!(EmailAddress::new("u@tt").is_ok()); + assert_eq!(EmailAddress::new("@d.tt").is_ok(), false); } use crate::chatlist::Chatlist;