user_email.rs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. use crate::errors::ErrorCode;
  2. use validator::validate_email;
  3. #[derive(Debug)]
  4. pub struct UserEmail(pub String);
  5. impl UserEmail {
  6. pub fn parse(s: String) -> Result<UserEmail, ErrorCode> {
  7. if s.trim().is_empty() {
  8. return Err(ErrorCode::EmailIsEmpty);
  9. }
  10. if validate_email(&s) {
  11. Ok(Self(s))
  12. } else {
  13. Err(ErrorCode::EmailFormatInvalid)
  14. }
  15. }
  16. }
  17. impl AsRef<str> for UserEmail {
  18. fn as_ref(&self) -> &str {
  19. &self.0
  20. }
  21. }
  22. #[cfg(test)]
  23. mod tests {
  24. use super::*;
  25. use claim::assert_err;
  26. use fake::{faker::internet::en::SafeEmail, Fake};
  27. #[test]
  28. fn empty_string_is_rejected() {
  29. let email = "".to_string();
  30. assert_err!(UserEmail::parse(email));
  31. }
  32. #[test]
  33. fn email_missing_at_symbol_is_rejected() {
  34. let email = "helloworld.com".to_string();
  35. assert_err!(UserEmail::parse(email));
  36. }
  37. #[test]
  38. fn email_missing_subject_is_rejected() {
  39. let email = "@domain.com".to_string();
  40. assert_err!(UserEmail::parse(email));
  41. }
  42. #[derive(Debug, Clone)]
  43. struct ValidEmailFixture(pub String);
  44. impl quickcheck::Arbitrary for ValidEmailFixture {
  45. fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
  46. let email = SafeEmail().fake_with_rng(g);
  47. Self(email)
  48. }
  49. }
  50. #[quickcheck_macros::quickcheck]
  51. fn valid_emails_are_parsed_successfully(valid_email: ValidEmailFixture) -> bool {
  52. UserEmail::parse(valid_email.0).is_ok()
  53. }
  54. }