dust_mail/client/
address.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4use crate::error::Result;
5
6use super::parser;
7
8#[derive(Debug)]
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10pub struct EmailAddress {
11    name: Option<String>,
12    email: String,
13}
14
15impl EmailAddress {
16    pub fn email(&self) -> &str {
17        &self.email
18    }
19
20    pub fn name(&self) -> Option<&String> {
21        self.name.as_ref()
22    }
23}
24
25impl Into<Address> for EmailAddress {
26    fn into(self) -> Address {
27        Address::Single(self)
28    }
29}
30
31impl From<email::Mailbox> for EmailAddress {
32    fn from(mailbox: email::Mailbox) -> Self {
33        Self::new(mailbox.name, mailbox.address)
34    }
35}
36
37impl EmailAddress {
38    pub fn new(name: Option<String>, email: String) -> Self {
39        Self { name, email }
40    }
41}
42
43#[derive(Debug)]
44#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
45pub enum Address {
46    Group {
47        name: Option<String>,
48        list: Vec<Address>,
49    },
50    Single(EmailAddress),
51}
52
53impl Address {
54    pub fn single(name: Option<String>, address: String) -> Self {
55        Address::Single(EmailAddress::new(name, address))
56    }
57
58    pub fn group(name: Option<String>, list: Vec<Self>) -> Self {
59        Self::Group { name, list }
60    }
61
62    pub fn as_list(&self) -> Vec<&EmailAddress> {
63        let mut addresses = Vec::new();
64
65        match self {
66            Address::Single(addr) => addresses.push(addr),
67            Address::Group { list, .. } => {
68                for addr in list {
69                    addresses.append(&mut addr.as_list());
70                }
71            }
72        }
73
74        addresses
75    }
76
77    pub fn first(&self) -> Option<&EmailAddress> {
78        match self {
79            Address::Group { list, .. } => {
80                for addr in list {
81                    if let Some(addr) = addr.first() {
82                        return Some(addr);
83                    }
84                }
85
86                None
87            }
88            Address::Single(addr) => Some(addr),
89        }
90    }
91}
92
93impl From<email::Address> for Address {
94    fn from(address: email::Address) -> Self {
95        match address {
96            email::Address::Group(name, list) => Self::group(
97                Some(name),
98                list.into_iter()
99                    .map(|item| EmailAddress::from(item).into())
100                    .collect::<Vec<Self>>(),
101            ),
102            email::Address::Mailbox(mailbox) => Self::Single(mailbox.into()),
103        }
104    }
105}
106
107impl<A: Into<Address>> From<Vec<A>> for Address {
108    fn from(mut list: Vec<A>) -> Self {
109        if list.len() == 1 {
110            let first = list.remove(0);
111
112            return first.into();
113        }
114
115        let iter = list.into_iter();
116
117        Self::group(None, iter.map(|addr| addr.into()).collect())
118    }
119}
120
121impl<N: Into<String>, A: Into<String>> From<(N, A)> for Address {
122    fn from((name, address): (N, A)) -> Self {
123        Self::Single(EmailAddress::new(Some(name.into()), address.into()))
124    }
125}
126
127impl<'a> Into<mail_builder::headers::address::Address<'a>> for Address {
128    fn into(self) -> mail_builder::headers::address::Address<'a> {
129        match self {
130            Address::Group { name, list } => mail_builder::headers::address::Address::new_group(
131                name,
132                list.into_iter().map(|item| item.into()).collect(),
133            ),
134            Address::Single(address) => {
135                mail_builder::headers::address::Address::new_address(address.name, address.email)
136            }
137        }
138    }
139}
140
141impl Address {
142    pub fn from_header<H: Into<String>>(header: H) -> Result<Vec<Self>> {
143        parser::address::address_list(header)
144    }
145}