sparklepost/transmission/
models.rs

1use serde::{
2    ser::{SerializeSeq, SerializeStruct, Serializer},
3    Serialize,
4};
5use serde_json::{to_value, Value};
6use std::convert::From;
7
8/// Email Recipient
9/// Example
10/// ```rust
11/// extern crate sparkpost;
12///
13/// use sparkpost::transmission::Recipient;
14///
15/// let recipient = Recipient::from("test@test.com");
16///  ```
17#[derive(Debug, Serialize, Default, PartialEq)]
18pub struct Recipient {
19    pub(crate) address: EmailAddress,
20    pub(crate) substitution_data: Option<Value>,
21}
22
23impl Recipient {
24    /// create recipient with substitute data for any type that implements Serialize from serde
25    pub fn with_substitution<T: Serialize>(
26        address: EmailAddress,
27        data: T,
28    ) -> Self {
29        Recipient {
30            address,
31            substitution_data: Some(
32                to_value(data).expect("unable to serialize data"),
33            ),
34        }
35    }
36}
37
38impl<'a> From<&'a str> for Recipient {
39    fn from(email: &'a str) -> Self {
40        email.to_owned().into()
41    }
42}
43
44impl From<String> for Recipient {
45    fn from(email: String) -> Self {
46        Recipient {
47            address: EmailAddress { email, name: None },
48            substitution_data: None,
49        }
50    }
51}
52
53impl From<EmailAddress> for Recipient {
54    fn from(address: EmailAddress) -> Self {
55        Recipient {
56            address,
57            substitution_data: None,
58        }
59    }
60}
61
62#[derive(Debug)]
63pub enum RecipientSet {
64    LocalList(Vec<Recipient>),
65    ListName(String),
66}
67
68impl Default for RecipientSet {
69    fn default() -> RecipientSet {
70        RecipientSet::LocalList(Vec::new())
71    }
72}
73
74impl Serialize for RecipientSet {
75    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
76    where
77        S: Serializer,
78    {
79        match self {
80            RecipientSet::LocalList(ref list) => {
81                let mut seq = serializer.serialize_seq(Some(list.len()))?;
82                for element in list {
83                    seq.serialize_element(element)?;
84                }
85                seq.end()
86            }
87            RecipientSet::ListName(ref list_name) => {
88                let mut s = serializer.serialize_struct("listname", 1)?;
89                s.serialize_field("list_id", list_name)?;
90                s.end()
91            }
92        }
93    }
94}
95
96/// Email address with optional name
97///
98/// ### Example
99/// ```rust
100/// use sparkpost::transmission::EmailAddress;
101///
102/// let address = EmailAddress::from("test@test.com");
103///
104/// // create address with name
105/// let address = EmailAddress::new("test@test.com", "Name");
106///
107///```
108#[derive(Debug, Serialize, Default, PartialEq)]
109pub struct EmailAddress {
110    pub(crate) email: String,
111    pub(crate) name: Option<String>,
112}
113
114impl EmailAddress {
115    /// create new email address with email and name
116    pub fn new<E: Into<String>, N: Into<String>>(email: E, name: N) -> Self {
117        EmailAddress {
118            email: email.into(),
119            name: Some(name.into()),
120        }
121    }
122}
123
124impl<'a> From<&'a str> for EmailAddress {
125    fn from(email: &'a str) -> Self {
126        EmailAddress {
127            email: email.to_owned(),
128            name: None,
129        }
130    }
131}
132
133impl From<String> for EmailAddress {
134    fn from(email: String) -> Self {
135        EmailAddress { email, name: None }
136    }
137}
138
139#[cfg(test)]
140mod test {
141    use super::*;
142    use serde_json::to_value;
143
144    #[derive(Debug, Serialize)]
145    struct Data {
146        name: String,
147    }
148
149    fn create_recipient() -> Recipient {
150        let data = Data {
151            name: "Name".to_owned(),
152        };
153        Recipient::with_substitution(create_address(), data)
154    }
155
156    fn create_address() -> EmailAddress {
157        EmailAddress {
158            email: "test@test.com".into(),
159            name: Some("Name".into()),
160        }
161    }
162
163    #[test]
164    fn address_with_new() {
165        let address = EmailAddress::new("test@test.com", "Name".to_string());
166        assert_eq!(address, create_address());
167
168        let address = EmailAddress::new("test@test.com".to_string(), "Name");
169        assert_eq!(address, create_address());
170
171        let address = EmailAddress::new("test@test.com", "Name");
172        assert_eq!(address, create_address());
173    }
174    #[test]
175    fn address() {
176        let address = EmailAddress::from("test@test.com".to_string());
177
178        assert_eq!("test@test.com", address.email.as_str());
179
180        let address = EmailAddress {
181            email: "test@test.com".into(),
182            name: Some("Name".into()),
183        };
184
185        assert_eq!(address, create_address())
186    }
187
188    #[test]
189    fn address_from_str() {
190        let address1: EmailAddress = "test@test.com".into();
191        let address2: EmailAddress = create_address();
192        assert_eq!(address1.email, address2.email);
193    }
194
195    #[test]
196    fn address_from_string() {
197        let address1: EmailAddress = String::from("test@test.com").into();
198        let address2: EmailAddress = create_address();
199        assert_eq!(address1.email, address2.email);
200    }
201
202    #[test]
203    fn address_with_name() {
204        let address = EmailAddress::new("test@test.com", "Name");
205        assert_eq!(address, create_address());
206    }
207
208    #[test]
209    fn recipient() {
210        let data = Data {
211            name: "Name".to_owned(),
212        };
213
214        let recipient = Recipient {
215            address: create_address(),
216            substitution_data: Some(to_value(data).unwrap()),
217        };
218        let string_value = "{\"address\":{\"email\":\"test@test.com\",\"name\":\"Name\"},\"substitution_data\":{\"name\":\"Name\"}}".to_owned();
219        assert_eq!(string_value, to_value(&recipient).unwrap().to_string());
220        assert_eq!(recipient, create_recipient());
221    }
222
223    #[test]
224    fn recipient_from_str() {
225        let recipient: Recipient = "test@test.com".into();
226
227        assert_eq!(recipient.address.email, create_recipient().address.email);
228    }
229}