refactor(types): extract the EmailAddress type to its own module

https://github.com/mozilla/fxa-email-service/pull/120
r=shane-tomlinson,brizental
This commit is contained in:
Phil Booth 2018-07-06 17:53:36 +01:00 коммит произвёл GitHub
Родитель ba9f8b88e2
Коммит 2102e32c75
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 81 добавлений и 64 удалений

35
src/email_address/mod.rs Normal file
Просмотреть файл

@ -0,0 +1,35 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
//! Email address type.
use serde::de::{Deserialize, Deserializer, Error, Unexpected};
use validate;
#[cfg(test)]
mod test;
#[derive(Clone, Debug, Default, Serialize, PartialEq)]
pub struct EmailAddress(pub String);
/// Email address type.
///
/// Validates and then lowercases the address during deserialization.
impl<'d> Deserialize<'d> for EmailAddress {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'d>,
{
let value: String = Deserialize::deserialize(deserializer)?;
if validate::email_address(&value) {
Ok(EmailAddress(value.to_lowercase()))
} else {
Err(D::Error::invalid_value(
Unexpected::Str(&value),
&"email address",
))
}
}
}

43
src/email_address/test.rs Normal file
Просмотреть файл

@ -0,0 +1,43 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// // file, you can obtain one at https://mozilla.org/MPL/2.0/.
use serde_test::{assert_de_tokens, Token};
use super::*;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct TestEmailStruct {
email: EmailAddress,
}
#[test]
fn always_lowercase_email() {
let expected = TestEmailStruct {
email: EmailAddress(String::from("foo@example.com")),
};
assert_de_tokens(
&expected,
&[
Token::Struct {
name: "TestEmailStruct",
len: 1,
},
Token::Str("email"),
Token::Str("foo@example.com"),
Token::StructEnd,
],
);
assert_de_tokens(
&expected,
&[
Token::Struct {
name: "TestEmailStruct",
len: 1,
},
Token::Str("email"),
Token::Str("FOO@EXAMPLE.COM"),
Token::StructEnd,
],
);
}

Просмотреть файл

@ -73,6 +73,7 @@ pub mod app_errors;
pub mod auth_db;
pub mod bounces;
pub mod duration;
pub mod email_address;
pub mod logging;
pub mod message_data;
pub mod providers;

Просмотреть файл

@ -11,11 +11,11 @@ use rocket::{
Data, Outcome, Request, State,
};
use rocket_contrib::{Json, Value};
use serde::de::{Deserialize, Deserializer, Error, Unexpected};
use app_errors::{AppError, AppErrorKind, AppResult};
use auth_db::DbClient;
use bounces::Bounces;
use email_address::EmailAddress;
use message_data::MessageData;
use providers::{Headers, Providers};
use validate;
@ -29,26 +29,6 @@ struct Body {
html: Option<String>,
}
#[derive(Clone, Debug, Default, Serialize, PartialEq)]
pub struct EmailAddress(pub String);
impl<'d> Deserialize<'d> for EmailAddress {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'d>,
{
let value: String = Deserialize::deserialize(deserializer)?;
if validate::email_address(&value) {
Ok(EmailAddress(value.to_lowercase()))
} else {
Err(D::Error::invalid_value(
Unexpected::Str(&value),
&"email address",
))
}
}
}
#[derive(Debug, Deserialize)]
struct Email {
to: EmailAddress,

Просмотреть файл

@ -7,9 +7,7 @@ use rocket::{
http::{ContentType, Status},
local::Client,
};
use serde_test::{assert_de_tokens, Token};
use super::EmailAddress;
use app_errors::{self, AppError, AppErrorKind};
use auth_db::DbClient;
use bounces::Bounces;
@ -43,46 +41,6 @@ fn setup() -> Client {
Client::new(server).unwrap()
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct TestEmailStruct {
email: EmailAddress,
}
#[test]
fn always_lowercase_email() {
let lowercase = TestEmailStruct {
email: EmailAddress(String::from("foo@example.com")),
};
assert_de_tokens(
&lowercase,
&[
Token::Struct {
name: "TestEmailStruct",
len: 1,
},
Token::Str("email"),
Token::Str("foo@example.com"),
Token::StructEnd,
],
);
let uppercase = TestEmailStruct {
email: EmailAddress(String::from("foo@example.com")),
};
assert_de_tokens(
&uppercase,
&[
Token::Struct {
name: "TestEmailStruct",
len: 1,
},
Token::Str("email"),
Token::Str("FOO@EXAMPLE.COM"),
Token::StructEnd,
],
);
}
#[test]
fn single_recipient() {
let client = setup();

Просмотреть файл

@ -13,8 +13,8 @@ use config::{Config, ConfigError, Environment, File};
use serde::de::{Deserialize, Deserializer, Error, Unexpected};
use duration::Duration;
use email_address::EmailAddress;
use logging::MozlogLogger;
use send::EmailAddress;
use serialize;
use validate;