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 auth_db;
|
||||||
pub mod bounces;
|
pub mod bounces;
|
||||||
pub mod duration;
|
pub mod duration;
|
||||||
|
pub mod email_address;
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
pub mod message_data;
|
pub mod message_data;
|
||||||
pub mod providers;
|
pub mod providers;
|
||||||
|
|
|
@ -11,11 +11,11 @@ use rocket::{
|
||||||
Data, Outcome, Request, State,
|
Data, Outcome, Request, State,
|
||||||
};
|
};
|
||||||
use rocket_contrib::{Json, Value};
|
use rocket_contrib::{Json, Value};
|
||||||
use serde::de::{Deserialize, Deserializer, Error, Unexpected};
|
|
||||||
|
|
||||||
use app_errors::{AppError, AppErrorKind, AppResult};
|
use app_errors::{AppError, AppErrorKind, AppResult};
|
||||||
use auth_db::DbClient;
|
use auth_db::DbClient;
|
||||||
use bounces::Bounces;
|
use bounces::Bounces;
|
||||||
|
use email_address::EmailAddress;
|
||||||
use message_data::MessageData;
|
use message_data::MessageData;
|
||||||
use providers::{Headers, Providers};
|
use providers::{Headers, Providers};
|
||||||
use validate;
|
use validate;
|
||||||
|
@ -29,26 +29,6 @@ struct Body {
|
||||||
html: Option<String>,
|
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)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct Email {
|
struct Email {
|
||||||
to: EmailAddress,
|
to: EmailAddress,
|
||||||
|
|
|
@ -7,9 +7,7 @@ use rocket::{
|
||||||
http::{ContentType, Status},
|
http::{ContentType, Status},
|
||||||
local::Client,
|
local::Client,
|
||||||
};
|
};
|
||||||
use serde_test::{assert_de_tokens, Token};
|
|
||||||
|
|
||||||
use super::EmailAddress;
|
|
||||||
use app_errors::{self, AppError, AppErrorKind};
|
use app_errors::{self, AppError, AppErrorKind};
|
||||||
use auth_db::DbClient;
|
use auth_db::DbClient;
|
||||||
use bounces::Bounces;
|
use bounces::Bounces;
|
||||||
|
@ -43,46 +41,6 @@ fn setup() -> Client {
|
||||||
Client::new(server).unwrap()
|
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]
|
#[test]
|
||||||
fn single_recipient() {
|
fn single_recipient() {
|
||||||
let client = setup();
|
let client = setup();
|
||||||
|
|
|
@ -13,8 +13,8 @@ use config::{Config, ConfigError, Environment, File};
|
||||||
use serde::de::{Deserialize, Deserializer, Error, Unexpected};
|
use serde::de::{Deserialize, Deserializer, Error, Unexpected};
|
||||||
|
|
||||||
use duration::Duration;
|
use duration::Duration;
|
||||||
|
use email_address::EmailAddress;
|
||||||
use logging::MozlogLogger;
|
use logging::MozlogLogger;
|
||||||
use send::EmailAddress;
|
|
||||||
use serialize;
|
use serialize;
|
||||||
use validate;
|
use validate;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче