Skip to main content

epp_client/contact/
create.rs

1//! Types for EPP contact create request
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use super::{ContactAuthInfo, Phone, PostalInfo, XMLNS};
7use crate::common::{NoExtension, StringValue};
8use crate::request::{Command, Transaction};
9
10impl<'a> Transaction<NoExtension> for ContactCreate<'a> {}
11
12impl<'a> Command for ContactCreate<'a> {
13    type Response = ContactCreateResponse;
14    const COMMAND: &'static str = "create";
15}
16
17// Request
18
19/// Type for elements under the contact &lt;create&gt; tag
20#[derive(Serialize, Debug)]
21pub struct Contact<'a> {
22    /// XML namespace for contact commands
23    #[serde(rename = "xmlns:contact")]
24    xmlns: &'a str,
25    /// Contact &lt;id&gt; tag
26    #[serde(rename = "contact:id")]
27    id: StringValue<'a>,
28    /// Contact &lt;postalInfo&gt; tag
29    #[serde(rename = "contact:postalInfo")]
30    postal_info: PostalInfo<'a>,
31    /// Contact &lt;voice&gt; tag
32    #[serde(rename = "contact:voice")]
33    voice: Phone<'a>,
34    /// Contact &lt;fax&gt; tag,
35    #[serde(rename = "contact:fax")]
36    fax: Option<Phone<'a>>,
37    /// Contact &lt;email&gt; tag
38    #[serde(rename = "contact:email")]
39    email: StringValue<'a>,
40    /// Contact &lt;authInfo&gt; tag
41    #[serde(rename = "contact:authInfo")]
42    auth_info: ContactAuthInfo<'a>,
43}
44
45#[derive(Serialize, Debug)]
46/// Type for EPP XML &lt;create&gt; command for contacts
47pub struct ContactCreate<'a> {
48    /// Data for &lt;create&gt; command for contact
49    #[serde(rename = "contact:create")]
50    pub contact: Contact<'a>,
51}
52
53impl<'a> ContactCreate<'a> {
54    pub fn new(
55        id: &'a str,
56        email: &'a str,
57        postal_info: PostalInfo<'a>,
58        voice: Phone<'a>,
59        auth_password: &'a str,
60    ) -> Self {
61        Self {
62            contact: Contact {
63                xmlns: XMLNS,
64                id: id.into(),
65                postal_info,
66                voice,
67                fax: None,
68                email: email.into(),
69                auth_info: ContactAuthInfo::new(auth_password),
70            },
71        }
72    }
73
74    /// Sets the &lt;fax&gt; data for the request
75    pub fn set_fax(&mut self, fax: Phone<'a>) {
76        self.contact.fax = Some(fax);
77    }
78}
79
80// Response
81
82/// Type that represents the &lt;creData&gt; tag for contact create response
83#[derive(Deserialize, Debug)]
84pub struct ContactCreateData {
85    /// The contact id
86    pub id: StringValue<'static>,
87    #[serde(rename = "crDate")]
88    /// The contact creation date
89    pub created_at: DateTime<Utc>,
90}
91
92/// Type that represents the &lt;resData&gt; tag for contact create response
93#[derive(Deserialize, Debug)]
94pub struct ContactCreateResponse {
95    /// Data under the &lt;creData&gt; tag
96    #[serde(rename = "creData")]
97    pub create_data: ContactCreateData,
98}
99
100#[cfg(test)]
101mod tests {
102    use chrono::{TimeZone, Utc};
103
104    use super::{ContactCreate, Phone, PostalInfo};
105    use crate::contact::Address;
106    use crate::response::ResultCode;
107    use crate::tests::{assert_serialized, response_from_file, CLTRID, SUCCESS_MSG, SVTRID};
108
109    #[test]
110    fn command() {
111        let street = &["58", "Orchid Road"];
112        let address = Address::new(street, "Paris", "Paris", "392374", "FR".parse().unwrap());
113        let postal_info = PostalInfo::new("int", "John Doe", "Acme Widgets", address);
114        let mut voice = Phone::new("+33.47237942");
115        voice.set_extension("123");
116        let mut fax = Phone::new("+33.86698799");
117        fax.set_extension("677");
118
119        let mut object = ContactCreate::new(
120            "eppdev-contact-3",
121            "contact@eppdev.net",
122            postal_info,
123            voice,
124            "eppdev-387323",
125        );
126        object.set_fax(fax);
127
128        assert_serialized("request/contact/create.xml", &object);
129    }
130
131    #[test]
132    fn response() {
133        let object = response_from_file::<ContactCreate>("response/contact/create.xml");
134        let results = object.res_data().unwrap();
135
136        assert_eq!(object.result.code, ResultCode::CommandCompletedSuccessfully);
137        assert_eq!(object.result.message, SUCCESS_MSG.into());
138        assert_eq!(results.create_data.id, "eppdev-contact-4".into());
139        assert_eq!(
140            results.create_data.created_at,
141            Utc.with_ymd_and_hms(2021, 7, 25, 16, 5, 32).unwrap(),
142        );
143        assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID.into());
144        assert_eq!(object.tr_ids.server_tr_id, SVTRID.into());
145    }
146}