epp_client/contact/
update.rs1use super::{ContactAuthInfo, Phone, PostalInfo, XMLNS};
4use crate::common::{NoExtension, ObjectStatus, StringValue};
5use crate::request::{Command, Transaction};
6use serde::Serialize;
7
8impl<'a> Transaction<NoExtension> for ContactUpdate<'a> {}
9
10impl<'a> Command for ContactUpdate<'a> {
11 type Response = ();
12 const COMMAND: &'static str = "update";
13}
14
15impl<'a> ContactUpdate<'a> {
16 pub fn new(id: &'a str) -> ContactUpdate {
17 Self {
18 contact: ContactUpdateRequestData {
19 xmlns: XMLNS,
20 id: id.into(),
21 add_statuses: None,
22 remove_statuses: None,
23 change_info: None,
24 },
25 }
26 }
27
28 pub fn set_info(
30 &mut self,
31 email: &'a str,
32 postal_info: PostalInfo<'a>,
33 voice: Phone<'a>,
34 auth_password: &'a str,
35 ) {
36 self.contact.change_info = Some(ContactChangeInfo {
37 email: Some(email.into()),
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 pub fn set_fax(&mut self, fax: Phone<'a>) {
47 if let Some(info) = &mut self.contact.change_info {
48 info.fax = Some(fax)
49 }
50 }
51
52 pub fn add(&mut self, status: &'a [ObjectStatus]) {
54 self.contact.add_statuses = Some(StatusList { status });
55 }
56
57 pub fn remove(&mut self, status: &'a [ObjectStatus]) {
59 self.contact.remove_statuses = Some(StatusList { status });
60 }
61}
62
63#[derive(Serialize, Debug)]
65pub struct ContactChangeInfo<'a> {
66 #[serde(rename = "contact:postalInfo")]
67 postal_info: Option<PostalInfo<'a>>,
68 #[serde(rename = "contact:voice")]
69 voice: Option<Phone<'a>>,
70 #[serde(rename = "contact:fax")]
71 fax: Option<Phone<'a>>,
72 #[serde(rename = "contact:email")]
73 email: Option<StringValue<'a>>,
74 #[serde(rename = "contact:authInfo")]
75 auth_info: Option<ContactAuthInfo<'a>>,
76}
77
78#[derive(Serialize, Debug)]
80pub struct StatusList<'a> {
81 #[serde(rename = "contact:status")]
82 status: &'a [ObjectStatus<'a>],
83}
84
85#[derive(Serialize, Debug)]
87pub struct ContactUpdateRequestData<'a> {
88 #[serde(rename = "xmlns:contact")]
89 xmlns: &'a str,
90 #[serde(rename = "contact:id")]
91 id: StringValue<'a>,
92 #[serde(rename = "contact:add")]
93 add_statuses: Option<StatusList<'a>>,
94 #[serde(rename = "contact:rem")]
95 remove_statuses: Option<StatusList<'a>>,
96 #[serde(rename = "contact:chg")]
97 change_info: Option<ContactChangeInfo<'a>>,
98}
99
100#[derive(Serialize, Debug)]
101pub struct ContactUpdate<'a> {
103 #[serde(rename = "contact:update")]
105 contact: ContactUpdateRequestData<'a>,
106}
107
108#[cfg(test)]
109mod tests {
110 use super::{ContactUpdate, Phone, PostalInfo};
111 use crate::common::ObjectStatus;
112 use crate::contact::Address;
113 use crate::response::ResultCode;
114 use crate::tests::{assert_serialized, response_from_file, CLTRID, SUCCESS_MSG, SVTRID};
115
116 #[test]
117 fn command() {
118 let mut object = ContactUpdate::new("eppdev-contact-3");
119
120 let street = &["58", "Orchid Road"];
121 let address = Address::new(street, "Paris", "Paris", "392374", "FR".parse().unwrap());
122 let postal_info = PostalInfo::new("loc", "John Doe", "Acme Widgets", address);
123 let voice = Phone::new("+33.47237942");
124
125 object.set_info("newemail@eppdev.net", postal_info, voice, "eppdev-387323");
126 let add_statuses = &[ObjectStatus {
127 status: "clientTransferProhibited".into(),
128 }];
129 object.add(add_statuses);
130 let remove_statuses = &[ObjectStatus {
131 status: "clientDeleteProhibited".into(),
132 }];
133 object.remove(remove_statuses);
134
135 assert_serialized("request/contact/update.xml", &object);
136 }
137
138 #[test]
139 fn contact_update() {
140 let object = response_from_file::<ContactUpdate>("response/contact/update.xml");
141 assert_eq!(object.result.code, ResultCode::CommandCompletedSuccessfully);
142 assert_eq!(object.result.message, SUCCESS_MSG.into());
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}