Use enum to represent RGP status values

This commit is contained in:
Dirkjan Ochtman 2024-05-27 11:10:16 +02:00
parent 65bf5f5595
commit 20e7acec3b
3 changed files with 85 additions and 24 deletions

View File

@ -2,8 +2,83 @@
//! //!
//! As described in [RFC 3915](https://tools.ietf.org/html/rfc3915). //! As described in [RFC 3915](https://tools.ietf.org/html/rfc3915).
use instant_xml::FromXml;
pub mod poll; // Technically a separate extension (different namespace, RFC) pub mod poll; // Technically a separate extension (different namespace, RFC)
pub mod report; pub mod report;
pub mod request; pub mod request;
#[derive(Debug, PartialEq)]
pub enum RgpStatus {
AddPeriod,
AutoRenewPeriod,
RenewPeriod,
TransferPeriod,
RedemptionPeriod,
PendingRestore,
PendingDelete,
}
impl<'xml> FromXml<'xml> for RgpStatus {
#[inline]
fn matches(id: ::instant_xml::Id<'_>, _: Option<::instant_xml::Id<'_>>) -> bool {
id == ::instant_xml::Id {
ns: XMLNS,
name: "rgpStatus",
} || id
== ::instant_xml::Id {
ns: poll::XMLNS,
name: "rgpStatus",
}
}
fn deserialize<'cx>(
into: &mut Self::Accumulator,
field: &'static str,
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
) -> Result<(), ::instant_xml::Error> {
use ::instant_xml::{Error, Id};
use instant_xml::de::Node;
let node = match deserializer.next() {
Some(result) => result?,
None => return Err(Error::MissingValue(field)),
};
let attr = match node {
Node::Attribute(attr) => attr,
Node::Open(_) | Node::Text(_) => return Err(Error::MissingValue(field)),
node => return Err(Error::UnexpectedNode(format!("{node:?} in RgpStatus"))),
};
let id = deserializer.attribute_id(&attr)?;
let expected = Id { ns: "", name: "s" };
if id != expected {
return Err(Error::MissingValue(field));
}
*into = Some(match attr.value.as_ref() {
"addPeriod" => Self::AddPeriod,
"autoRenewPeriod" => Self::AutoRenewPeriod,
"renewPeriod" => Self::RenewPeriod,
"transferPeriod" => Self::TransferPeriod,
"redemptionPeriod" => Self::RedemptionPeriod,
"pendingRestore" => Self::PendingRestore,
"pendingDelete" => Self::PendingDelete,
val => {
return Err(Error::UnexpectedValue(format!(
"invalid RgpStatus '{val:?}'"
)))
}
});
deserializer.ignore()?;
Ok(())
}
type Accumulator = Option<Self>;
const KIND: ::instant_xml::Kind = ::instant_xml::Kind::Element;
}
pub const XMLNS: &str = "urn:ietf:params:xml:ns:rgp-1.0"; pub const XMLNS: &str = "urn:ietf:params:xml:ns:rgp-1.0";

View File

@ -3,6 +3,8 @@
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use instant_xml::FromXml; use instant_xml::FromXml;
use super::RgpStatus;
/// RGP request status /// RGP request status
#[derive(Debug, FromXml)] #[derive(Debug, FromXml)]
#[xml(rename = "pollData", ns(XMLNS), rename_all = "camelCase")] #[xml(rename = "pollData", ns(XMLNS), rename_all = "camelCase")]
@ -13,19 +15,11 @@ pub struct RgpPollData {
pub report_due_date: DateTime<Utc>, pub report_due_date: DateTime<Utc>,
} }
/// Type that represents the `<rgpStatus>` tag for domain rgp restore request response pub(super) const XMLNS: &str = "http://www.verisign.com/epp/rgp-poll-1.0";
#[derive(Debug, FromXml)]
#[xml(rename = "rgpStatus", ns(XMLNS))]
pub struct RgpStatus {
/// The domain RGP status
#[xml(rename = "s", attribute)]
pub status: String,
}
const XMLNS: &str = "http://www.verisign.com/epp/rgp-poll-1.0";
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use crate::poll::{Poll, PollData}; use crate::poll::{Poll, PollData};
use crate::tests::response_from_file; use crate::tests::response_from_file;
@ -37,6 +31,6 @@ mod tests {
}; };
assert_eq!(data.name, "EXAMPLE.COM"); assert_eq!(data.name, "EXAMPLE.COM");
assert_eq!(data.rgp_status.status, "pendingRestore"); assert_eq!(data.rgp_status, RgpStatus::PendingRestore);
} }
} }

View File

@ -7,7 +7,7 @@ use crate::{
request::{Extension, Transaction}, request::{Extension, Transaction},
}; };
use super::XMLNS; use super::{RgpStatus, XMLNS};
impl<'a> Transaction<Update<RgpRestoreRequest<'a>>> for DomainUpdate<'a> {} impl<'a> Transaction<Update<RgpRestoreRequest<'a>>> for DomainUpdate<'a> {}
@ -42,15 +42,6 @@ impl Default for RgpRestoreRequest<'static> {
// Response // Response
/// Type that represents the `<rgpStatus>` tag for domain rgp restore request response
#[derive(Debug, FromXml)]
#[xml(rename = "rgpStatus", ns(XMLNS))]
pub struct RgpStatus {
/// The domain RGP status
#[xml(rename = "s", attribute)]
pub status: String,
}
#[derive(Debug, FromXml)] #[derive(Debug, FromXml)]
#[xml(rename = "upData", ns(XMLNS))] #[xml(rename = "upData", ns(XMLNS))]
/// Type that represents the `<resData>` tag for domain transfer response /// Type that represents the `<resData>` tag for domain transfer response
@ -81,6 +72,7 @@ mod tests {
use crate::domain::info::DomainInfo; use crate::domain::info::DomainInfo;
use crate::domain::update::{DomainChangeInfo, DomainUpdate}; use crate::domain::update::{DomainChangeInfo, DomainUpdate};
use crate::extensions::rgp::request::RgpRequestResponse; use crate::extensions::rgp::request::RgpRequestResponse;
use crate::extensions::rgp::RgpStatus;
use crate::response::ResultCode; use crate::response::ResultCode;
use crate::tests::{assert_serialized, response_from_file_with_ext, SUCCESS_MSG, SVTRID}; use crate::tests::{assert_serialized, response_from_file_with_ext, SUCCESS_MSG, SVTRID};
@ -120,7 +112,7 @@ mod tests {
_ => panic!("Unexpected response type"), _ => panic!("Unexpected response type"),
}; };
assert_eq!(data.rgp_status[0].status, "pendingRestore".to_string()); assert_eq!(data.rgp_status[0], RgpStatus::PendingRestore);
assert_eq!(object.tr_ids.server_tr_id, SVTRID); assert_eq!(object.tr_ids.server_tr_id, SVTRID);
} }
@ -136,7 +128,7 @@ mod tests {
_ => panic!("Unexpected response type"), _ => panic!("Unexpected response type"),
}; };
assert_eq!(data.rgp_status[0].status, "addPeriod"); assert_eq!(data.rgp_status[0], RgpStatus::AddPeriod);
assert_eq!(data.rgp_status[1].status, "renewPeriod"); assert_eq!(data.rgp_status[1], RgpStatus::RenewPeriod);
} }
} }