oparl_types/
email_address.rs1#[derive(
7 Debug,
8 Clone,
9 PartialEq,
10 Eq,
11 Hash,
12 derive_more::AsRef,
13 derive_more::Display,
14 derive_more::From,
15 derive_more::FromStr,
16 derive_more::Into,
17 serde::Serialize,
18 serde::Deserialize,
19)]
20pub struct EmailAddress(email_address::EmailAddress);
21
22impl EmailAddress {
23 pub fn as_str(&self) -> &str {
24 self.0.as_str()
25 }
26}
27
28impl PartialOrd for EmailAddress {
29 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
30 Some(self.cmp(other))
31 }
32}
33
34impl Ord for EmailAddress {
35 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
36 self.as_str().cmp(other.as_str())
37 }
38}
39
40impl TryFrom<String> for EmailAddress {
41 type Error = email_address::Error;
42
43 fn try_from(value: String) -> Result<Self, Self::Error> {
44 value.parse()
45 }
46}
47
48#[cfg(feature = "sea-orm")]
49mod sea_orm_impls {
50 use sea_orm::{
51 sea_query::{ArrayType, Nullable, ValueType, ValueTypeErr},
52 ColumnType, DbErr, TryGetError, TryGetable, Value,
53 };
54
55 use super::EmailAddress;
56
57 impl From<EmailAddress> for Value {
58 fn from(value: EmailAddress) -> Self {
59 value.as_str().into()
60 }
61 }
62
63 impl TryGetable for EmailAddress {
64 fn try_get_by<I: sea_orm::ColIdx>(
65 res: &sea_orm::QueryResult,
66 index: I,
67 ) -> Result<Self, TryGetError> {
68 let s = <String as TryGetable>::try_get_by(res, index)?;
69 s.try_into().map_err(|e| {
70 DbErr::TryIntoErr {
71 from: "String",
72 into: "EmailAddress",
73 source: Box::new(e),
74 }
75 .into()
76 })
77 }
78 }
79
80 impl ValueType for EmailAddress {
81 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
82 let s = <String as ValueType>::try_from(v)?;
83 s.try_into().map_err(|_| ValueTypeErr)
84 }
85
86 fn type_name() -> String {
87 stringify!(String).to_owned()
88 }
89
90 fn array_type() -> ArrayType {
91 <String as ValueType>::array_type()
92 }
93
94 fn column_type() -> ColumnType {
95 <String as ValueType>::column_type()
96 }
97 }
98
99 impl Nullable for EmailAddress {
100 fn null() -> Value {
101 Value::String(None)
102 }
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::EmailAddress;
109
110 use pretty_assertions::assert_eq;
111
112 #[test]
113 fn from_str() {
114 assert_eq!(
115 EmailAddress(
116 "hello@example.com"
117 .parse()
118 .expect("value must be a parseable EmailAddress")
119 ),
120 "hello@example.com"
121 .parse()
122 .expect("value must be a parseable EmailAddress")
123 );
124 }
125}
126
127#[cfg(test)]
128mod serde_tests {
129 use super::EmailAddress;
130 use pretty_assertions::assert_eq;
131 use serde_json::json;
132
133 #[test]
134 fn serialize() {
135 assert_eq!(
136 json!(EmailAddress(
137 "hello@example.com"
138 .parse()
139 .expect("value must be a parseable EmailAddress")
140 )),
141 json!("hello@example.com")
142 );
143 }
144
145 #[test]
146 fn deserialize_good() {
147 let deserialized: EmailAddress = serde_json::from_value(json!("hello@example.com"))
148 .expect("value must be deserializable as EmailAddress");
149 assert_eq!(
150 deserialized,
151 EmailAddress(
152 "hello@example.com"
153 .parse()
154 .expect("value must be a parseable EmailAddress")
155 )
156 );
157 }
158
159 #[test]
160 fn deserialize_bad() {
161 assert!(serde_json::from_value::<EmailAddress>(json!("xyzabcd")).is_err());
162 assert!(serde_json::from_value::<EmailAddress>(json!(true)).is_err());
163 assert!(serde_json::from_value::<EmailAddress>(json!(123)).is_err());
164 }
165}