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:
Родитель
ba9f8b88e2
Коммит
2102e32c75
|
@ -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",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче