Skip to main content

idkollen_client/models/
email.rs

1use fmt::Display;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::fmt;
4use thiserror::Error;
5
6/// A validated email address.
7///
8/// Constructed via [`Email::parse`]; serializes/deserializes as a plain JSON string.
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct Email(String);
11
12#[derive(Debug, Error)]
13#[error("invalid email address: {0}")]
14pub struct EmailError(String);
15
16impl Email {
17    pub fn parse(s: &str) -> Result<Self, EmailError> {
18        s.parse::<email_address::EmailAddress>()
19            .map_err(|e| EmailError(e.to_string()))?;
20
21        Ok(Self(s.to_owned()))
22    }
23
24    #[inline]
25    #[must_use]
26    pub fn as_str(&self) -> &str {
27        &self.0
28    }
29}
30
31impl From<Email> for String {
32    #[inline]
33    fn from(e: Email) -> String {
34        e.0
35    }
36}
37
38impl AsRef<str> for Email {
39    #[inline]
40    fn as_ref(&self) -> &str {
41        &self.0
42    }
43}
44
45impl Display for Email {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        f.write_str(&self.0)
48    }
49}
50
51impl Serialize for Email {
52    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
53        self.0.serialize(s)
54    }
55}
56
57impl<'de> Deserialize<'de> for Email {
58    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
59        let s = String::deserialize(d)?;
60
61        Email::parse(&s).map_err(serde::de::Error::custom)
62    }
63}