diff --git a/epp-client/src/common.rs b/epp-client/src/common.rs index 7b5ec42..2f2a9bb 100644 --- a/epp-client/src/common.rs +++ b/epp-client/src/common.rs @@ -3,7 +3,9 @@ use std::{fmt::Display, str::FromStr}; use epp_client_macros::ElementName; -use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; +use serde::{ + de::Error as DeError, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer, +}; use crate::request::EppExtension; @@ -267,6 +269,99 @@ impl Period { } } +#[derive(Deserialize, Debug, PartialEq)] +#[serde(untagged)] +pub enum Status { + OK, + ClientDeleteProhibited, + ClientHold, + ClientRenewProhibited, + ClientTransferProhibited, + ClientUpdateProhibited, + Inactive, + PendingCreate, + PendingDelete, + PendingRenew, + PendingTransfer, + PendingUpdate, + ServerDeleteProhibited, + ServerHold, + ServerRenewProhibited, + ServerTransferProhibited, + ServerUpdateProhibited, +} + +impl Serialize for Status { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let enum_str = match self { + Status::OK => "ok", + Status::ClientDeleteProhibited => "clientDeleteProhibited", + Status::ClientHold => "clientHold", + Status::ClientRenewProhibited => "clientRenewProhibited", + Status::ClientTransferProhibited => "clientTransferProhibited", + Status::ClientUpdateProhibited => "clientUpdateProhibited", + Status::Inactive => "inactive", + Status::PendingCreate => "pendingCreate", + Status::PendingDelete => "pendingDelete", + Status::PendingRenew => "pemdingRenew", + Status::PendingTransfer => "pendingTransfer", + Status::PendingUpdate => "pendingUpdate", + Status::ServerDeleteProhibited => "serverDeleteProhibited", + Status::ServerHold => "serverHold", + Status::ServerRenewProhibited => "serverRenewProhibited", + Status::ServerTransferProhibited => "serverTransferProhibited", + Status::ServerUpdateProhibited => "serverUpdateProhibited", + }; + + serializer.serialize_str(&enum_str) + } +} + +impl<'de> Deserialize<'de> for ContactStatusWithEnum { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let contact_status = DeserializeStatus::deserialize(deserializer)?; + + let status = match contact_status.status.as_str() { + "ok" => Status::OK, + "clientDeleteProhibited" => Status::ClientDeleteProhibited, + "clientHold" => Status::ClientHold, + "clientRenewProhibited" => Status::ClientRenewProhibited, + "clientTransferProhibited" => Status::ClientTransferProhibited, + "clientUpdateProhibited" => Status::ClientUpdateProhibited, + "inactive" => Status::Inactive, + "pendingCreate" => Status::PendingCreate, + "pendingDelete" => Status::PendingDelete, + "pemdingRenew" => Status::PendingRenew, + "pendingTransfer" => Status::PendingTransfer, + "pendingUpdate" => Status::PendingUpdate, + "serverDeleteProhibited" => Status::ServerDeleteProhibited, + "serverHold" => Status::ServerHold, + "serverRenewProhibited" => Status::ServerRenewProhibited, + "serverTransferProhibited" => Status::ServerTransferProhibited, + "serverUpdateProhibited" => Status::ServerUpdateProhibited, + _ => return Err("Status Deserialization Error").map_err(DeError::custom), + }; + + Ok(ContactStatusWithEnum { status: status }) + } +} + +type DeserializeStatus = ContactStatus; + +/// The <status> type on contact transactions +#[derive(Serialize, Debug)] +pub struct ContactStatusWithEnum { + /// The status name, represented by the 's' attr on <status> tags + #[serde(rename = "s")] + pub status: Status, +} + /// The <status> type on contact transactions #[derive(Serialize, Deserialize, Debug)] pub struct ContactStatus { diff --git a/epp-client/src/contact/info.rs b/epp-client/src/contact/info.rs index 0af462f..5cebd84 100644 --- a/epp-client/src/contact/info.rs +++ b/epp-client/src/contact/info.rs @@ -4,7 +4,8 @@ use epp_client_macros::*; use super::XMLNS; use crate::common::{ - ContactAuthInfo, ContactStatus, ElementName, NoExtension, Phone, PostalInfo, StringValue, + ContactAuthInfo, ContactStatusWithEnum, ElementName, NoExtension, Phone, PostalInfo, + StringValue, }; use crate::request::{EppExtension, EppRequest}; use serde::{Deserialize, Serialize}; @@ -135,7 +136,7 @@ pub struct ContactInfoData { pub roid: StringValue, /// The list of contact statuses #[serde(rename = "status")] - pub statuses: Vec, + pub statuses: Vec, /// The postal info for the contact #[serde(rename = "postalInfo")] pub postal_info: PostalInfo, diff --git a/epp-client/src/contact/update.rs b/epp-client/src/contact/update.rs index 465112b..e767f50 100644 --- a/epp-client/src/contact/update.rs +++ b/epp-client/src/contact/update.rs @@ -4,7 +4,7 @@ use epp_client_macros::*; use super::XMLNS; use crate::common::{ - ContactAuthInfo, ContactStatus, ElementName, NoExtension, Phone, PostalInfo, StringValue, + ContactAuthInfo, ContactStatusWithEnum, ElementName, NoExtension, Phone, PostalInfo, StringValue, }; use crate::request::{EppExtension, EppRequest}; use crate::response::EppCommandResponse; @@ -131,12 +131,12 @@ impl ContactUpdate { } /// Sets the data for the <add> tag for the contact update request - pub fn add(&mut self, statuses: Vec) { + pub fn add(&mut self, statuses: Vec) { self.request.contact.add_statuses = Some(StatusList { status: statuses }); } /// Sets the data for the <rem> tag for the contact update request - pub fn remove(&mut self, statuses: Vec) { + pub fn remove(&mut self, statuses: Vec) { self.request.contact.remove_statuses = Some(StatusList { status: statuses }); } } @@ -160,7 +160,7 @@ pub struct ContactChangeInfo { #[derive(Serialize, Deserialize, Debug)] pub struct StatusList { #[serde(rename = "contact:status", alias = "status")] - status: Vec, + status: Vec, } /// Type for elements under the contact <update> tag diff --git a/epp-client/src/tests/de.rs b/epp-client/src/tests/de.rs index 75772b2..587eebb 100644 --- a/epp-client/src/tests/de.rs +++ b/epp-client/src/tests/de.rs @@ -3,7 +3,7 @@ mod response { use super::super::get_xml; use super::super::CLTRID; - use crate::common::NoExtension; + use crate::common::{NoExtension, Status}; use crate::contact::check::ContactCheck; use crate::contact::create::ContactCreate; use crate::contact::delete::ContactDelete; @@ -168,6 +168,8 @@ mod response { let xml = get_xml("response/contact/info.xml").unwrap(); let object = ContactInfo::::deserialize_response(xml.as_str()).unwrap(); + println!("{:?}", object); + let result = object.res_data().unwrap(); let fax = result.info_data.fax.as_ref().unwrap(); let voice_ext = result.info_data.voice.extension.as_ref().unwrap(); @@ -178,7 +180,7 @@ mod response { assert_eq!(object.result.message, SUCCESS_MSG.into()); assert_eq!(result.info_data.id, "eppdev-contact-3".into()); assert_eq!(result.info_data.roid, "UNDEF-ROID".into()); - assert_eq!(result.info_data.statuses[0].status, "ok".to_string()); + assert_eq!(result.info_data.statuses[0].status, Status::OK); assert_eq!(result.info_data.postal_info.info_type, "loc".to_string()); assert_eq!(result.info_data.postal_info.name, "John Doe".into()); assert_eq!( diff --git a/epp-client/src/tests/se.rs b/epp-client/src/tests/se.rs index a084d6a..52ddc44 100644 --- a/epp-client/src/tests/se.rs +++ b/epp-client/src/tests/se.rs @@ -8,7 +8,7 @@ mod request { use crate::common::HostObjList; use crate::common::NoExtension; use crate::common::{ - Address, ContactStatus, DomainAuthInfo, DomainContact, DomainStatus, HostAddr, HostAttr, + Address, ContactStatusWithEnum, Status, DomainAuthInfo, DomainContact, DomainStatus, HostAddr, HostAttr, HostStatus, Phone, PostalInfo, }; use crate::contact::check::ContactCheck; @@ -137,12 +137,12 @@ mod request { let voice = Phone::new("+33.47237942"); object.set_info("newemail@eppdev.net", postal_info, voice, "eppdev-387323"); - let add_statuses = vec![ContactStatus { - status: "clientTransferProhibited".to_string(), + let add_statuses = vec![ContactStatusWithEnum { + status: Status::ClientTransferProhibited, }]; object.add(add_statuses); - let remove_statuses = vec![ContactStatus { - status: "clientDeleteProhibited".to_string(), + let remove_statuses = vec![ContactStatusWithEnum { + status: Status::ClientDeleteProhibited, }]; object.remove(remove_statuses);