instant_epp/contact/
update.rs

1//! Types for EPP contact create request
2
3use instant_xml::ToXml;
4
5use super::{ContactAuthInfo, Fax, PostalInfo, Status, Voice, XMLNS};
6use crate::common::{NoExtension, EPP_XMLNS};
7use crate::request::{Command, Transaction};
8
9impl<'a> Transaction<NoExtension> for ContactUpdate<'a> {}
10
11impl<'a> Command for ContactUpdate<'a> {
12    type Response = ();
13    const COMMAND: &'static str = "update";
14}
15
16impl<'a> ContactUpdate<'a> {
17    pub fn new(id: &'a str) -> ContactUpdate {
18        Self {
19            contact: ContactUpdateRequest {
20                id,
21                add_statuses: None,
22                remove_statuses: None,
23                change_info: None,
24            },
25        }
26    }
27
28    /// Sets the data for the `<chg>` tag for the contact update request
29    pub fn set_info(
30        &mut self,
31        email: &'a str,
32        postal_info: PostalInfo<'a>,
33        voice: Voice<'a>,
34        auth_password: &'a str,
35    ) {
36        self.contact.change_info = Some(ContactChangeInfo {
37            email: Some(email),
38            postal_info: Some(postal_info),
39            voice: Some(voice),
40            auth_info: Some(ContactAuthInfo::new(auth_password)),
41            fax: None,
42        });
43    }
44
45    /// Sets the data for the `<fax>` tag under `<chg>` for the contact update request
46    pub fn set_fax(&mut self, fax: Fax<'a>) {
47        if let Some(info) = &mut self.contact.change_info {
48            info.fax = Some(fax)
49        }
50    }
51
52    /// Sets the data for the `<add>` tag for the contact update request
53    pub fn add(&mut self, statuses: &'a [Status]) {
54        self.contact.add_statuses = Some(AddStatuses { statuses });
55    }
56
57    /// Sets the data for the `<rem>` tag for the contact update request
58    pub fn remove(&mut self, statuses: &'a [Status]) {
59        self.contact.remove_statuses = Some(RemoveStatuses { statuses });
60    }
61}
62
63/// Type for elements under the `<chg>` tag for contact update request
64#[derive(Debug, ToXml)]
65#[xml(rename = "chg", ns(XMLNS))]
66pub struct ContactChangeInfo<'a> {
67    postal_info: Option<PostalInfo<'a>>,
68    voice: Option<Voice<'a>>,
69    fax: Option<Fax<'a>>,
70    email: Option<&'a str>,
71    auth_info: Option<ContactAuthInfo<'a>>,
72}
73
74/// Type for list of elements of the `<status>` tag for contact update request
75#[derive(Debug, ToXml)]
76pub struct StatusList<'a> {
77    status: &'a [Status],
78}
79
80#[derive(Debug, ToXml)]
81#[xml(rename = "add", ns(XMLNS))]
82struct AddStatuses<'a> {
83    statuses: &'a [Status],
84}
85
86#[derive(Debug, ToXml)]
87#[xml(rename = "rem", ns(XMLNS))]
88struct RemoveStatuses<'a> {
89    statuses: &'a [Status],
90}
91
92/// Type for elements under the contact `<update>` tag
93#[derive(Debug, ToXml)]
94#[xml(rename = "update", ns(XMLNS))]
95pub struct ContactUpdateRequest<'a> {
96    id: &'a str,
97    add_statuses: Option<AddStatuses<'a>>,
98    #[xml(rename = "rem")]
99    remove_statuses: Option<RemoveStatuses<'a>>,
100    change_info: Option<ContactChangeInfo<'a>>,
101}
102
103/// Type for EPP XML `<update>` command for contacts
104#[derive(Debug, ToXml)]
105#[xml(rename = "update", ns(EPP_XMLNS))]
106pub struct ContactUpdate<'a> {
107    /// The data under the `<update>` tag for the contact update
108    contact: ContactUpdateRequest<'a>,
109}
110
111#[cfg(test)]
112mod tests {
113    use super::{ContactUpdate, PostalInfo, Status, Voice};
114    use crate::contact::Address;
115    use crate::response::ResultCode;
116    use crate::tests::{assert_serialized, response_from_file, CLTRID, SUCCESS_MSG, SVTRID};
117
118    #[test]
119    fn command() {
120        let mut object = ContactUpdate::new("eppdev-contact-3");
121
122        let street = &["58", "Orchid Road"];
123        let address = Address::new(
124            street,
125            "Paris",
126            Some("Paris"),
127            Some("392374"),
128            "FR".parse().unwrap(),
129        );
130        let postal_info = PostalInfo::new("loc", "John Doe", Some("Acme Widgets"), address);
131        let voice = Voice::new("+33.47237942");
132
133        object.set_info("newemail@eppdev.net", postal_info, voice, "eppdev-387323");
134        object.add(&[Status::ClientTransferProhibited]);
135        object.remove(&[Status::ClientDeleteProhibited]);
136
137        assert_serialized("request/contact/update.xml", &object);
138    }
139
140    #[test]
141    fn contact_update() {
142        let object = response_from_file::<ContactUpdate>("response/contact/update.xml");
143        assert_eq!(object.result.code, ResultCode::CommandCompletedSuccessfully);
144        assert_eq!(object.result.message, SUCCESS_MSG);
145        assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
146        assert_eq!(object.tr_ids.server_tr_id, SVTRID);
147    }
148}