Make Transaction trait more flexible

Instead of separate types implementing the `Transaction` trait,
here we implement `Transaction` for a command type.

The definition of the `Transaction` trait ensures that:

* Implementations for commands with a particular extension
  must be explicitly defined (that is, you can't just call
  `transact()` with a random combination of a command type
  and an extension type).
* The combination of the command type and the extension type
  (via the `Transaction` impl) defines the response type
  (both the command response and the extension response).

This definition means that:

* `Transaction` implementations for commands defined within
  the epp-client crate that want to use an extension defined
  within the crate must have an impl local to the crate.
* `Transaction` impls defined for commands foreign to the
  epp-client crate as well as impls defined with extensions
  foreign to the crate can have an impl in their defining crate.
This commit is contained in:
Dirkjan Ochtman 2021-12-09 10:17:00 +01:00 committed by masalachai
parent 38d4391e43
commit d34c94ee9f
33 changed files with 771 additions and 1556 deletions

View File

@ -36,20 +36,21 @@
//! println!("{:?}", greeting);
//!
//! // Execute an EPP Command against the registry with distinct request and response objects
//! let domain_check = DomainCheck::<NoExtension>::new(vec!["eppdev.com", "eppdev.net"]);
//! let domain_check = DomainCheck::new(vec!["eppdev.com", "eppdev.net"]);
//! let response = client.transact(domain_check, "transaction-id").await.unwrap();
//! println!("{:?}", response);
//!
//! }
//! ```
use std::{error::Error, fmt::Debug};
use std::error::Error;
use crate::common::NoExtension;
use crate::config::EppClientConfig;
use crate::error;
use crate::hello::{Greeting, GreetingDocument, HelloDocument};
use crate::registry::{epp_connect, EppConnection};
use crate::request::{EppExtension, Transaction};
use crate::request::{Command, Extension, Transaction};
use crate::response::Response;
use crate::xml::EppXml;
@ -87,20 +88,21 @@ impl EppClient {
Ok(GreetingDocument::deserialize(&response)?.data)
}
pub async fn transact<T, E>(
pub async fn transact<C, E>(
&mut self,
request: T,
data: impl Into<RequestData<C, E>>,
id: &str,
) -> Result<Response<<T as Transaction<E>>::Output, E::Response>, error::Error>
) -> Result<Response<C::Response, E::Response>, error::Error>
where
T: Transaction<E> + Debug,
E: EppExtension,
C: Transaction<E> + Command,
E: Extension,
{
let epp_xml = request.serialize_request(id)?;
let data = data.into();
let epp_xml = <C as Transaction<E>>::serialize_request(data.command, data.extension, id)?;
let response = self.connection.transact(&epp_xml).await?;
T::deserialize_response(&response)
C::deserialize_response(&response)
}
/// Accepts raw EPP XML and returns the raw EPP XML response to it.
@ -119,3 +121,26 @@ impl EppClient {
GreetingDocument::deserialize(&self.connection.greeting).map(|obj| obj.data)
}
}
pub struct RequestData<C, E> {
command: C,
extension: Option<E>,
}
impl<C: Command> From<C> for RequestData<C, NoExtension> {
fn from(command: C) -> Self {
Self {
command,
extension: None,
}
}
}
impl<C: Command, E: Extension> From<(C, E)> for RequestData<C, E> {
fn from((command, extension): (C, E)) -> Self {
Self {
command,
extension: Some(extension),
}
}
}

View File

@ -2,10 +2,9 @@
use std::{fmt::Display, str::FromStr};
use epp_client_macros::ElementName;
use serde::{Deserialize, Serialize};
use crate::request::EppExtension;
use crate::request::Extension;
pub(crate) const EPP_XMLNS: &str = "urn:ietf:params:xml:ns:epp-1.0";
@ -37,12 +36,11 @@ pub trait ElementName {
const ELEMENT: &'static str;
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "empty")]
#[derive(Serialize, Deserialize, Debug, PartialEq)]
/// An empty placeholder tag. To be refactored to something more compliant later.
pub struct NoExtension;
impl EppExtension for NoExtension {
impl Extension for NoExtension {
type Response = NoExtension;
}

View File

@ -1,58 +1,18 @@
use std::fmt::Debug;
/// Types for EPP contact check request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{NoExtension, StringValue};
use crate::request::{Transaction, Command};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct ContactCheck<E> {
request: ContactCheckRequest,
extension: Option<E>,
}
impl<E: EppExtension> Transaction<E> for ContactCheck<E> {
type Input = ContactCheckRequest;
type Output = ContactCheckResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> ContactCheck<E> {
pub fn new(contact_ids: &[&str]) -> ContactCheck<NoExtension> {
let contact_ids = contact_ids
.iter()
.map(|&d| d.into())
.collect::<Vec<StringValue>>();
ContactCheck {
request: ContactCheckRequest {
list: ContactList {
xmlns: XMLNS.to_string(),
contact_ids,
},
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> ContactCheck<F> {
ContactCheck {
request: self.request,
extension: Some(extension),
}
}
}
impl Transaction<NoExtension> for ContactCheck {}
// Request
/// Type that represents the &lt;check&gt; command for contact transactions
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct ContactList {
/// The XML namespace for the contact &lt;check&gt;
#[serde(rename = "xmlns:contact", alias = "xmlns")]
@ -62,19 +22,39 @@ pub struct ContactList {
pub contact_ids: Vec<StringValue>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "check")]
#[derive(Serialize, Debug)]
/// The &lt;command&gt; type for contact check command
pub struct ContactCheckRequest {
pub struct ContactCheck {
/// The &lt;check&gt; tag for the contact check command
#[serde(rename = "contact:check", alias = "check")]
list: ContactList,
}
impl ContactCheck {
pub fn new(contact_ids: &[&str]) -> Self {
let contact_ids = contact_ids
.iter()
.map(|&d| d.into())
.collect::<Vec<StringValue>>();
Self {
list: ContactList {
xmlns: XMLNS.to_string(),
contact_ids,
},
}
}
}
impl Command for ContactCheck {
type Response = ContactCheckResponse;
const COMMAND: &'static str = "check";
}
// Response
/// Type that represents the &lt;id&gt; tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct ContactAvailable {
/// The text of the &lt;id&gt; tag
#[serde(rename = "$value")]
@ -85,7 +65,7 @@ pub struct ContactAvailable {
}
/// Type that represents the &lt;cd&gt; tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct ContactCheckResponseDataItem {
/// Data under the &lt;id&gt; tag
#[serde(rename = "id")]
@ -95,18 +75,15 @@ pub struct ContactCheckResponseDataItem {
}
/// Type that represents the &lt;chkData&gt; tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct ContactCheckResponseData {
/// XML namespace for contact response data
#[serde(rename = "xmlns:contact")]
xmlns: String,
/// Data under the &lt;cd&gt; tag
#[serde(rename = "cd")]
pub contact_list: Vec<ContactCheckResponseDataItem>,
}
/// Type that represents the &lt;resData&gt; tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct ContactCheckResponse {
/// Data under the &lt;chkData&gt; tag
#[serde(rename = "chkData")]

View File

@ -1,68 +1,21 @@
//! Types for EPP contact create request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ContactAuthInfo, ElementName, NoExtension, Phone, PostalInfo, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{ContactAuthInfo, NoExtension, Phone, PostalInfo, StringValue};
use crate::request::{Transaction, Command};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct ContactCreate<E> {
request: ContactCreateRequest,
extension: Option<E>,
}
impl Transaction<NoExtension> for ContactCreate {}
impl<E: EppExtension> Transaction<E> for ContactCreate<E> {
type Input = ContactCreateRequest;
type Output = ContactCreateResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> ContactCreate<E> {
pub fn new(
id: &str,
email: &str,
postal_info: PostalInfo,
voice: Phone,
auth_password: &str,
) -> ContactCreate<NoExtension> {
ContactCreate {
request: ContactCreateRequest {
contact: Contact {
xmlns: XMLNS.to_string(),
id: id.into(),
postal_info,
voice,
fax: None,
email: email.into(),
auth_info: ContactAuthInfo::new(auth_password),
},
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> ContactCreate<F> {
ContactCreate {
request: self.request,
extension: Some(extension),
}
}
/// Sets the &lt;fax&gt; data for the request
pub fn set_fax(&mut self, fax: Phone) {
self.request.contact.fax = Some(fax);
}
impl Command for ContactCreate {
type Response = ContactCreateResponse;
const COMMAND: &'static str = "create";
}
// Request
/// Type for elements under the contact &lt;create&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct Contact {
/// XML namespace for contact commands
#[serde(rename = "xmlns:contact", alias = "xmlns")]
@ -87,15 +40,41 @@ pub struct Contact {
auth_info: ContactAuthInfo,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "create")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;create&gt; command for contacts
pub struct ContactCreateRequest {
pub struct ContactCreate {
/// Data for &lt;create&gt; command for contact
#[serde(rename = "contact:create", alias = "create")]
pub contact: Contact,
}
impl ContactCreate {
pub fn new(
id: &str,
email: &str,
postal_info: PostalInfo,
voice: Phone,
auth_password: &str,
) -> Self {
Self {
contact: Contact {
xmlns: XMLNS.to_string(),
id: id.into(),
postal_info,
voice,
fax: None,
email: email.into(),
auth_info: ContactAuthInfo::new(auth_password),
},
}
}
/// Sets the &lt;fax&gt; data for the request
pub fn set_fax(&mut self, fax: Phone) {
self.contact.fax = Some(fax);
}
}
// Response
/// Type that represents the &lt;creData&gt; tag for contact create response

View File

@ -1,51 +1,19 @@
//! Types for EPP contact delete request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::response::ResponseStatus;
use serde::{Deserialize, Serialize};
use crate::common::{NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::Serialize;
#[derive(Debug)]
pub struct ContactDelete<E> {
request: ContactDeleteRequest,
extension: Option<E>,
}
impl Transaction<NoExtension> for ContactDelete {}
impl<E: EppExtension> Transaction<E> for ContactDelete<E> {
type Input = ContactDeleteRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> ContactDelete<E> {
pub fn new(id: &str) -> ContactDelete<NoExtension> {
ContactDelete {
request: ContactDeleteRequest {
contact: ContactDeleteRequestData {
xmlns: XMLNS.to_string(),
id: id.into(),
},
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> ContactDelete<F> {
ContactDelete {
request: self.request,
extension: Some(extension),
}
}
impl Command for ContactDelete {
type Response = ();
const COMMAND: &'static str = "delete";
}
/// Type containing the data for the &lt;delete&gt; tag for contacts
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct ContactDeleteRequestData {
/// XML namespace for the &lt;delete&gt; command for contacts
#[serde(rename = "xmlns:contact", alias = "xmlns")]
@ -55,11 +23,21 @@ pub struct ContactDeleteRequestData {
id: StringValue,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "delete")]
#[derive(Serialize, Debug)]
/// The &lt;delete&gt; type for the contact delete EPP command
pub struct ContactDeleteRequest {
pub struct ContactDelete {
#[serde(rename = "contact:delete", alias = "delete")]
/// The data for the &lt;delete&gt; tag for a contact delete command
contact: ContactDeleteRequestData,
}
impl ContactDelete {
pub fn new(id: &str) -> ContactDelete {
Self {
contact: ContactDeleteRequestData {
xmlns: XMLNS.to_string(),
id: id.into(),
},
}
}
}

View File

@ -1,55 +1,21 @@
//! Types for EPP contact info request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{
ContactAuthInfo, ContactStatus, ElementName, NoExtension, Phone, PostalInfo, StringValue,
};
use crate::request::{EppExtension, Transaction};
use crate::common::{ContactAuthInfo, ContactStatus, NoExtension, Phone, PostalInfo, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct ContactInfo<E> {
request: ContactInfoRequest,
extension: Option<E>,
}
impl Transaction<NoExtension> for ContactInfo {}
impl<E: EppExtension> Transaction<E> for ContactInfo<E> {
type Input = ContactInfoRequest;
type Output = ContactInfoResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> ContactInfo<E> {
pub fn new(id: &str, auth_password: &str) -> ContactInfo<NoExtension> {
ContactInfo {
request: ContactInfoRequest {
info: ContactInfoRequestData {
xmlns: XMLNS.to_string(),
id: id.into(),
auth_info: ContactAuthInfo::new(auth_password),
},
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> ContactInfo<F> {
ContactInfo {
request: self.request,
extension: Some(extension),
}
}
impl Command for ContactInfo {
type Response = ContactInfoResponse;
const COMMAND: &'static str = "info";
}
// Request
/// Type for elements under the contact &lt;info&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct ContactInfoRequestData {
/// XML namespace for contact commands
#[serde(rename = "xmlns:contact", alias = "contact")]
@ -62,23 +28,31 @@ pub struct ContactInfoRequestData {
auth_info: ContactAuthInfo,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "info")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;info&gt; command for contacts
pub struct ContactInfoRequest {
pub struct ContactInfo {
/// Data for &lt;info&gt; command for contact
#[serde(rename = "contact:info", alias = "info")]
info: ContactInfoRequestData,
}
impl ContactInfo {
pub fn new(id: &str, auth_password: &str) -> ContactInfo {
Self {
info: ContactInfoRequestData {
xmlns: XMLNS.to_string(),
id: id.into(),
auth_info: ContactAuthInfo::new(auth_password),
},
}
}
}
// Response
/// Type that represents the &lt;infData&gt; tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct ContactInfoData {
/// XML namespace for contact response data
#[serde(rename = "xmlns:contact")]
xmlns: String,
/// The contact id
pub id: StringValue,
/// The contact ROID
@ -119,7 +93,7 @@ pub struct ContactInfoData {
}
/// Type that represents the &lt;resData&gt; tag for contact info response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct ContactInfoResponse {
/// Data under the &lt;infData&gt; tag
#[serde(rename = "infData")]

View File

@ -1,50 +1,27 @@
//! Types for EPP contact create request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{
ContactAuthInfo, ContactStatus, ElementName, NoExtension, Phone, PostalInfo, StringValue,
};
use crate::request::{EppExtension, Transaction};
use crate::response::ResponseStatus;
use serde::{Deserialize, Serialize};
use crate::common::{ContactAuthInfo, ContactStatus, NoExtension, Phone, PostalInfo, StringValue};
use crate::request::{Command, Transaction};
use serde::Serialize;
#[derive(Debug)]
pub struct ContactUpdate<E> {
request: ContactUpdateRequest,
extension: Option<E>,
impl Transaction<NoExtension> for ContactUpdate {}
impl Command for ContactUpdate {
type Response = ();
const COMMAND: &'static str = "update";
}
impl<E: EppExtension> Transaction<E> for ContactUpdate<E> {
type Input = ContactUpdateRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> ContactUpdate<E> {
pub fn new(id: &str) -> ContactUpdate<NoExtension> {
ContactUpdate {
request: ContactUpdateRequest {
contact: ContactUpdateRequestData {
xmlns: XMLNS.to_string(),
id: id.into(),
add_statuses: None,
remove_statuses: None,
change_info: None,
},
impl ContactUpdate {
pub fn new(id: &str) -> ContactUpdate {
Self {
contact: ContactUpdateRequestData {
xmlns: XMLNS.to_string(),
id: id.into(),
add_statuses: None,
remove_statuses: None,
change_info: None,
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> ContactUpdate<F> {
ContactUpdate {
request: self.request,
extension: Some(extension),
}
}
@ -56,7 +33,7 @@ impl<E: EppExtension> ContactUpdate<E> {
voice: Phone,
auth_password: &str,
) {
self.request.contact.change_info = Some(ContactChangeInfo {
self.contact.change_info = Some(ContactChangeInfo {
email: Some(email.into()),
postal_info: Some(postal_info),
voice: Some(voice),
@ -67,24 +44,24 @@ impl<E: EppExtension> ContactUpdate<E> {
/// Sets the data for the &lt;fax&gt; tag under &lt;chg&gt; for the contact update request
pub fn set_fax(&mut self, fax: Phone) {
if let Some(info) = &mut self.request.contact.change_info {
if let Some(info) = &mut self.contact.change_info {
info.fax = Some(fax)
}
}
/// Sets the data for the &lt;add&gt; tag for the contact update request
pub fn add(&mut self, statuses: Vec<ContactStatus>) {
self.request.contact.add_statuses = Some(StatusList { status: statuses });
self.contact.add_statuses = Some(StatusList { status: statuses });
}
/// Sets the data for the &lt;rem&gt; tag for the contact update request
pub fn remove(&mut self, statuses: Vec<ContactStatus>) {
self.request.contact.remove_statuses = Some(StatusList { status: statuses });
self.contact.remove_statuses = Some(StatusList { status: statuses });
}
}
/// Type for elements under the &lt;chg&gt; tag for contact update request
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct ContactChangeInfo {
#[serde(rename = "contact:postalInfo", alias = "postalInfo")]
postal_info: Option<PostalInfo>,
@ -99,14 +76,14 @@ pub struct ContactChangeInfo {
}
/// Type for list of elements of the &lt;status&gt; tag for contact update request
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct StatusList {
#[serde(rename = "contact:status", alias = "status")]
status: Vec<ContactStatus>,
}
/// Type for elements under the contact &lt;update&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct ContactUpdateRequestData {
#[serde(rename = "xmlns:contact", alias = "xmlns")]
xmlns: String,
@ -120,10 +97,9 @@ pub struct ContactUpdateRequestData {
change_info: Option<ContactChangeInfo>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;update&gt; command for contacts
pub struct ContactUpdateRequest {
pub struct ContactUpdate {
/// The data under the &lt;update&gt; tag for the contact update
#[serde(rename = "contact:update", alias = "update")]
contact: ContactUpdateRequestData,

View File

@ -1,47 +1,27 @@
//! Types for EPP domain check request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct DomainCheck<E> {
request: DomainCheckRequest,
extension: Option<E>,
impl Transaction<NoExtension> for DomainCheck {}
impl Command for DomainCheck {
type Response = DomainCheckResponse;
const COMMAND: &'static str = "check";
}
impl<E: EppExtension> Transaction<E> for DomainCheck<E> {
type Input = DomainCheckRequest;
type Output = DomainCheckResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> DomainCheck<E> {
pub fn new(domains: Vec<&str>) -> DomainCheck<NoExtension> {
DomainCheck {
request: DomainCheckRequest {
list: DomainList {
xmlns: XMLNS.to_string(),
domains: domains
.into_iter()
.map(|d| d.into())
.collect::<Vec<StringValue>>(),
},
impl DomainCheck {
pub fn new(domains: Vec<&str>) -> Self {
Self {
list: DomainList {
xmlns: XMLNS.to_string(),
domains: domains
.into_iter()
.map(|d| d.into())
.collect::<Vec<StringValue>>(),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainCheck<F> {
DomainCheck {
request: self.request,
extension: Some(extension),
}
}
}
@ -49,7 +29,7 @@ impl<E: EppExtension> DomainCheck<E> {
// Request
/// Type for &lt;name&gt; elements under the domain &lt;check&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainList {
#[serde(rename = "xmlns:domain", alias = "xmlns")]
/// XML namespace for domain commands
@ -59,10 +39,9 @@ pub struct DomainList {
pub domains: Vec<StringValue>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "check")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;check&gt; command for domains
pub struct DomainCheckRequest {
pub struct DomainCheck {
/// The object holding the list of domains to be checked
#[serde(rename = "domain:check", alias = "check")]
list: DomainList,
@ -71,7 +50,7 @@ pub struct DomainCheckRequest {
// Response
/// Type that represents the &lt;name&gt; tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainAvailable {
/// The domain name
#[serde(rename = "$value")]
@ -82,7 +61,7 @@ pub struct DomainAvailable {
}
/// Type that represents the &lt;cd&gt; tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainCheckResponseDataItem {
/// Data under the &lt;name&gt; tag
#[serde(rename = "name")]
@ -92,18 +71,15 @@ pub struct DomainCheckResponseDataItem {
}
/// Type that represents the &lt;chkData&gt; tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainCheckResponseData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// Data under the &lt;cd&gt; tag
#[serde(rename = "cd")]
pub domain_list: Vec<DomainCheckResponseDataItem>,
}
/// Type that represents the &lt;resData&gt; tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainCheckResponse {
/// Data under the &lt;chkData&gt; tag
#[serde(rename = "chkData")]

View File

@ -1,69 +1,21 @@
//! Types for EPP domain create request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{
DomainAuthInfo, DomainContact, ElementName, HostList, NoExtension, Period, StringValue,
};
use crate::request::{EppExtension, Transaction};
use crate::common::{DomainAuthInfo, DomainContact, HostList, NoExtension, Period, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct DomainCreate<E> {
request: DomainCreateRequest,
extension: Option<E>,
}
impl Transaction<NoExtension> for DomainCreate {}
impl<E: EppExtension> Transaction<E> for DomainCreate<E> {
type Input = DomainCreateRequest;
type Output = DomainCreateResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> DomainCreate<E> {
pub fn new(
name: &str,
period: u16,
ns: Option<HostList>,
registrant_id: Option<&str>,
auth_password: &str,
contacts: Option<Vec<DomainContact>>,
) -> DomainCreate<NoExtension> {
let registrant = registrant_id.map(|id| id.into());
let domain_create = DomainCreateRequest {
domain: DomainCreateRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: Period::new(period),
ns,
registrant,
auth_info: DomainAuthInfo::new(auth_password),
contacts,
},
};
DomainCreate {
request: domain_create,
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainCreate<F> {
DomainCreate {
request: self.request,
extension: Some(extension),
}
}
impl Command for DomainCreate {
type Response = DomainCreateResponse;
const COMMAND: &'static str = "create";
}
// Request
/// Type for elements under the domain &lt;create&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainCreateRequestData {
/// XML namespace for domain commands
#[serde(rename = "xmlns:domain", alias = "xmlns")]
@ -89,10 +41,9 @@ pub struct DomainCreateRequestData {
pub auth_info: DomainAuthInfo,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "create")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;create&gt; command for domains
pub struct DomainCreateRequest {
pub struct DomainCreate {
/// The data for the domain to be created with
/// T being the type of nameserver list (`HostObjList` or `HostAttrList`)
/// to be supplied
@ -100,10 +51,33 @@ pub struct DomainCreateRequest {
pub domain: DomainCreateRequestData,
}
impl DomainCreate {
pub fn new(
name: &str,
period: u16,
ns: Option<HostList>,
registrant_id: Option<&str>,
auth_password: &str,
contacts: Option<Vec<DomainContact>>,
) -> Self {
Self {
domain: DomainCreateRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: Period::new(period),
ns,
registrant: registrant_id.map(|id| id.into()),
auth_info: DomainAuthInfo::new(auth_password),
contacts,
},
}
}
}
// Response
/// Type that represents the &lt;chkData&gt; tag for domain create response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainCreateResponseData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
@ -119,7 +93,7 @@ pub struct DomainCreateResponseData {
}
/// Type that represents the &lt;resData&gt; tag for domain create response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainCreateResponse {
/// Data under the &lt;chkData&gt; tag
#[serde(rename = "creData")]

View File

@ -1,51 +1,30 @@
//! Types for EPP domain delete request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::response::ResponseStatus;
use serde::{Deserialize, Serialize};
use crate::common::{NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::Serialize;
#[derive(Debug)]
pub struct DomainDelete<E> {
request: DomainDeleteRequest,
extension: Option<E>,
impl Transaction<NoExtension> for DomainDelete {}
impl Command for DomainDelete {
type Response = ();
const COMMAND: &'static str = "delete";
}
impl<E: EppExtension> Transaction<E> for DomainDelete<E> {
type Input = DomainDeleteRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> DomainDelete<E> {
pub fn new(name: &str) -> DomainDelete<NoExtension> {
DomainDelete {
request: DomainDeleteRequest {
domain: DomainDeleteRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
},
impl DomainDelete {
pub fn new(name: &str) -> Self {
Self {
domain: DomainDeleteRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainDelete<F> {
DomainDelete {
request: self.request,
extension: Some(extension),
}
}
}
/// Type for &lt;name&gt; element under the domain &lt;delete&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainDeleteRequestData {
/// XML namespace for domain commands
#[serde(rename = "xmlns:domain", alias = "xmlns")]
@ -55,10 +34,9 @@ pub struct DomainDeleteRequestData {
name: StringValue,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "delete")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;delete&gt; command for domains
pub struct DomainDeleteRequest {
pub struct DomainDelete {
/// The data under the &lt;delete&gt; tag for domain deletion
#[serde(rename = "domain:delete", alias = "delete")]
domain: DomainDeleteRequestData,

View File

@ -1,52 +1,32 @@
//! Types for EPP domain info request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{
DomainAuthInfo, DomainContact, DomainStatus, ElementName, HostAttr, NoExtension, StringValue,
DomainAuthInfo, DomainContact, DomainStatus, HostAttr, NoExtension, StringValue,
};
use crate::request::{EppExtension, Transaction};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct DomainInfo<E> {
request: DomainInfoRequest,
extension: Option<E>,
impl Transaction<NoExtension> for DomainInfo {}
impl Command for DomainInfo {
type Response = DomainInfoResponse;
const COMMAND: &'static str = "info";
}
impl<E: EppExtension> Transaction<E> for DomainInfo<E> {
type Input = DomainInfoRequest;
type Output = DomainInfoResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> DomainInfo<E> {
pub fn new(name: &str, auth_password: Option<&str>) -> DomainInfo<NoExtension> {
DomainInfo {
request: DomainInfoRequest {
info: DomainInfoRequestData {
xmlns: XMLNS.to_string(),
domain: Domain {
hosts: "all".to_string(),
name: name.to_string(),
},
auth_info: auth_password.map(|password| DomainAuthInfo {
password: password.into(),
}),
impl DomainInfo {
pub fn new(name: &str, auth_password: Option<&str>) -> Self {
Self {
info: DomainInfoRequestData {
xmlns: XMLNS.to_string(),
domain: Domain {
hosts: "all".to_string(),
name: name.to_string(),
},
auth_info: auth_password.map(|password| DomainAuthInfo {
password: password.into(),
}),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainInfo<F> {
DomainInfo {
request: self.request,
extension: Some(extension),
}
}
}
@ -54,7 +34,7 @@ impl<E: EppExtension> DomainInfo<E> {
// Request
/// Type for data under the &lt;name&gt; element tag for the domain &lt;info&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct Domain {
/// The hosts attribute. Default value is "all"
hosts: String,
@ -64,7 +44,7 @@ pub struct Domain {
}
/// Type for &lt;name&gt; element under the domain &lt;info&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainInfoRequestData {
/// XML namespace for domain commands
#[serde(rename = "xmlns:domain", alias = "xmlns")]
@ -77,10 +57,9 @@ pub struct DomainInfoRequestData {
auth_info: Option<DomainAuthInfo>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "info")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;info&gt; command for domains
pub struct DomainInfoRequest {
pub struct DomainInfo {
/// The data under the &lt;info&gt; tag for domain info
#[serde(rename = "domain:info", alias = "info")]
info: DomainInfoRequestData,
@ -90,7 +69,7 @@ pub struct DomainInfoRequest {
/// The two types of ns lists, hostObj and hostAttr, that may be returned in the
/// domain info response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainNsList {
/// List of &lt;hostObj&gt; ns elements
#[serde(rename = "hostObj")]
@ -100,11 +79,8 @@ pub struct DomainNsList {
}
/// Type that represents the &lt;infData&gt; tag for domain info response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainInfoResponseData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// The domain name
pub name: StringValue,
/// The domain ROID
@ -150,7 +126,7 @@ pub struct DomainInfoResponseData {
}
/// Type that represents the &lt;resData&gt; tag for domain info response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainInfoResponse {
/// Data under the &lt;resData&gt; tag
#[serde(rename = "infData")]

View File

@ -1,48 +1,28 @@
//! Types for EPP domain renew request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, NoExtension, Period, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{NoExtension, Period, StringValue};
use crate::request::{Command, Transaction};
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct DomainRenew<E> {
request: DomainRenewRequest,
extension: Option<E>,
impl Transaction<NoExtension> for DomainRenew {}
impl Command for DomainRenew {
type Response = DomainRenewResponse;
const COMMAND: &'static str = "renew";
}
impl<E: EppExtension> Transaction<E> for DomainRenew<E> {
type Input = DomainRenewRequest;
type Output = DomainRenewResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> DomainRenew<E> {
pub fn new(name: &str, current_expiry_date: NaiveDate, years: u16) -> DomainRenew<NoExtension> {
impl DomainRenew {
pub fn new(name: &str, current_expiry_date: NaiveDate, years: u16) -> Self {
let exp_date_str = current_expiry_date.format("%Y-%m-%d").to_string().into();
DomainRenew {
request: DomainRenewRequest {
domain: DomainRenewRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
current_expiry_date: exp_date_str,
period: Period::new(years),
},
Self {
domain: DomainRenewRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
current_expiry_date: exp_date_str,
period: Period::new(years),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainRenew<F> {
DomainRenew {
request: self.request,
extension: Some(extension),
}
}
}
@ -50,7 +30,7 @@ impl<E: EppExtension> DomainRenew<E> {
// Request
/// Type for data under the domain &lt;renew&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainRenewRequestData {
/// XML namespace for domain commands
#[serde(rename = "xmlns:domain", alias = "xmlns")]
@ -66,10 +46,9 @@ pub struct DomainRenewRequestData {
period: Period,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "renew")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;renew&gt; command for domains
pub struct DomainRenewRequest {
pub struct DomainRenew {
/// The data under the &lt;renew&gt; tag for the domain renewal
#[serde(rename = "domain:renew", alias = "renew")]
domain: DomainRenewRequestData,
@ -78,11 +57,8 @@ pub struct DomainRenewRequest {
// Response
/// Type that represents the &lt;renData&gt; tag for domain renew response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainRenewResponseData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// The name of the domain
pub name: StringValue,
/// The new expiry date after renewal
@ -91,7 +67,7 @@ pub struct DomainRenewResponseData {
}
/// Type that represents the &lt;resData&gt; tag for domain renew response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainRenewResponse {
/// Data under the &lt;renData&gt; tag
#[serde(rename = "renData")]

View File

@ -1,411 +1,75 @@
//! Types for EPP domain transfer request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{DomainAuthInfo, ElementName, NoExtension, Period, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{DomainAuthInfo, NoExtension, Period, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct DomainTransferRequest<E> {
request: DomainTransferReq,
extension: Option<E>,
impl Transaction<NoExtension> for DomainTransfer {}
impl Command for DomainTransfer {
type Response = DomainTransferResponse;
const COMMAND: &'static str = "transfer";
}
impl<E: EppExtension> Transaction<E> for DomainTransferRequest<E> {
type Input = DomainTransferReq;
type Output = DomainTransferResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
#[derive(Debug)]
pub struct DomainTransferApprove<E> {
request: DomainTransferReq,
extension: Option<E>,
}
impl<E: EppExtension> Transaction<E> for DomainTransferApprove<E> {
type Input = DomainTransferReq;
type Output = DomainTransferResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
#[derive(Debug)]
pub struct DomainTransferReject<E> {
request: DomainTransferReq,
extension: Option<E>,
}
impl<E: EppExtension> Transaction<E> for DomainTransferReject<E> {
type Input = DomainTransferReq;
type Output = DomainTransferResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
#[derive(Debug)]
pub struct DomainTransferCancel<E> {
request: DomainTransferReq,
extension: Option<E>,
}
impl<E: EppExtension> Transaction<E> for DomainTransferCancel<E> {
type Input = DomainTransferReq;
type Output = DomainTransferResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
#[derive(Debug)]
pub struct DomainTransferQuery<E> {
request: DomainTransferReq,
extension: Option<E>,
}
impl<E: EppExtension> Transaction<E> for DomainTransferQuery<E> {
type Input = DomainTransferReq;
type Output = DomainTransferResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
/// Type that represents the &lt;epp&gt; request for transfer request for domain
///
/// ## Usage
///
/// ```no_run
/// use std::collections::HashMap;
///
/// use epp_client::config::{EppClientConfig, RegistryConfig};
/// use epp_client::EppClient;
/// use epp_client::domain::transfer::DomainTransferRequest;
/// use epp_client::common::NoExtension;
/// use epp_client::login::Login;
/// use epp_client::logout::Logout;
///
/// #[tokio::main]
/// async fn main() {
/// // Create a config
/// let mut registry: HashMap<String, RegistryConfig> = HashMap::new();
/// registry.insert(
/// "registry_name".to_owned(),
/// RegistryConfig {
/// host: "example.com".to_owned(),
/// port: 700,
/// tls_files: None,
/// },
/// );
/// let config = EppClientConfig { registry };
///
/// // Create an instance of EppClient, passing the config and the registry you want to connect to
/// let mut client = match EppClient::new(&config, "registry_name").await {
/// Ok(client) => client,
/// Err(e) => panic!("Failed to create EppClient: {}", e)
/// };
///
/// let login = Login::<NoExtension>::new("username", "password", None);
/// client.transact(login, "transaction-id").await.unwrap();
///
/// // Create an DomainTransferRequest instance
/// let domain_transfer_request = DomainTransferRequest::<NoExtension>::new(
/// "eppdev-100.net", None, "epP4uthd#v"
/// );
///
/// // send it to the registry and receive a response of type DomainTransferRequestResponse
/// let response = client.transact(domain_transfer_request, "transaction-id").await.unwrap();
///
/// println!("{:?}", response);
///
/// let logout = Logout::<NoExtension>::new();
/// client.transact(logout, "transaction-id").await.unwrap();
/// }
/// ```
impl<E: EppExtension> DomainTransferRequest<E> {
pub fn new(
name: &str,
years: Option<u16>,
auth_password: &str,
) -> DomainTransferRequest<NoExtension> {
DomainTransferRequest {
request: DomainTransferReq {
operation: "request".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: years.map(Period::new),
auth_info: Some(DomainAuthInfo::new(auth_password)),
},
impl DomainTransfer {
pub fn new(name: &str, years: Option<u16>, auth_password: &str) -> Self {
Self {
operation: "request".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: years.map(Period::new),
auth_info: Some(DomainAuthInfo::new(auth_password)),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainTransferRequest<F> {
DomainTransferRequest {
request: self.request,
extension: Some(extension),
}
}
}
impl<E: EppExtension> DomainTransferApprove<E> {
pub fn new(name: &str) -> DomainTransferApprove<NoExtension> {
DomainTransferApprove {
request: DomainTransferReq {
operation: "approve".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: None,
},
pub fn query(name: &str, auth_password: &str) -> Self {
Self {
operation: "query".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: Some(DomainAuthInfo::new(auth_password)),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainTransferApprove<F> {
DomainTransferApprove {
request: self.request,
extension: Some(extension),
}
}
}
/// Type that represents the &lt;epp&gt; request for transfer rejection for domains
///
/// ## Usage
///
/// ```no_run
/// use std::collections::HashMap;
///
/// use epp_client::config::{EppClientConfig, RegistryConfig};
/// use epp_client::EppClient;
/// use epp_client::domain::transfer::DomainTransferReject;
/// use epp_client::common::NoExtension;
/// use epp_client::login::Login;
/// use epp_client::logout::Logout;
///
/// #[tokio::main]
/// async fn main() {
/// // Create a config
/// let mut registry: HashMap<String, RegistryConfig> = HashMap::new();
/// registry.insert(
/// "registry_name".to_owned(),
/// RegistryConfig {
/// host: "example.com".to_owned(),
/// port: 700,
/// tls_files: None,
/// },
/// );
/// let config = EppClientConfig { registry };
///
/// // Create an instance of EppClient, passing the config and the registry you want to connect to
/// let mut client = match EppClient::new(&config, "registry_name").await {
/// Ok(client) => client,
/// Err(e) => panic!("Failed to create EppClient: {}", e)
/// };
///
/// let login = Login::<NoExtension>::new("username", "password", None);
/// client.transact(login, "transaction-id").await.unwrap();
///
/// // Create an DomainTransferReject instance
/// let domain_transfer_reject = DomainTransferReject::<NoExtension>::new(
/// "eppdev-100.net"
/// );
///
/// // send it to the registry and receive a response of type DomainTransferRejectResponse
/// let response = client.transact(domain_transfer_reject, "transaction-id").await.unwrap();
///
/// println!("{:?}", response);
///
/// let logout = Logout::<NoExtension>::new();
/// client.transact(logout, "transaction-id").await.unwrap();
/// }
/// ```
impl<E: EppExtension> DomainTransferReject<E> {
pub fn new(name: &str) -> DomainTransferReject<NoExtension> {
DomainTransferReject {
request: DomainTransferReq {
operation: "reject".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: None,
},
pub fn approve(name: &str) -> Self {
Self {
operation: "approve".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: None,
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainTransferReject<F> {
DomainTransferReject {
request: self.request,
extension: Some(extension),
}
}
}
/// Type that represents the &lt;epp&gt; request for transfer request cancellation for domains
///
/// ## Usage
///
/// ```no_run
/// use std::collections::HashMap;
///
/// use epp_client::config::{EppClientConfig, RegistryConfig};
/// use epp_client::EppClient;
/// use epp_client::domain::transfer::DomainTransferCancel;
/// use epp_client::common::NoExtension;
/// use epp_client::login::Login;
/// use epp_client::logout::Logout;
///
/// #[tokio::main]
/// async fn main() {
/// // Create a config
/// let mut registry: HashMap<String, RegistryConfig> = HashMap::new();
/// registry.insert(
/// "registry_name".to_owned(),
/// RegistryConfig {
/// host: "example.com".to_owned(),
/// port: 700,
/// tls_files: None,
/// },
/// );
/// let config = EppClientConfig { registry };
///
/// // Create an instance of EppClient, passing the config and the registry you want to connect to
/// let mut client = match EppClient::new(&config, "registry_name").await {
/// Ok(client) => client,
/// Err(e) => panic!("Failed to create EppClient: {}", e)
/// };
///
/// let login = Login::<NoExtension>::new("username", "password", None);
/// client.transact(login, "transaction-id").await.unwrap();
///
/// // Create an DomainTransferCancel instance
/// let domain_transfer_cancel = DomainTransferCancel::<NoExtension>::new(
/// "eppdev-100.net"
/// );
///
/// // send it to the registry and receive a response of type DomainTransferCancelResponse
/// let response = client.transact(domain_transfer_cancel, "transaction-id").await.unwrap();
///
/// println!("{:?}", response);
///
/// let logout = Logout::<NoExtension>::new();
/// client.transact(logout, "transaction-id").await.unwrap();
/// }
/// ```
impl<E: EppExtension> DomainTransferCancel<E> {
pub fn new(name: &str) -> DomainTransferCancel<NoExtension> {
DomainTransferCancel {
request: DomainTransferReq {
operation: "cancel".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: None,
},
pub fn reject(name: &str) -> Self {
Self {
operation: "reject".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: None,
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainTransferCancel<F> {
DomainTransferCancel {
request: self.request,
extension: Some(extension),
}
}
}
/// Type that represents the &lt;epp&gt; request for transfer request query for domains
///
/// ## Usage
///
/// ```no_run
/// use std::collections::HashMap;
///
/// use epp_client::config::{EppClientConfig, RegistryConfig};
/// use epp_client::EppClient;
/// use epp_client::domain::transfer::DomainTransferQuery;
/// use epp_client::common::NoExtension;
/// use epp_client::login::Login;
/// use epp_client::logout::Logout;
///
/// #[tokio::main]
/// async fn main() {
/// // Create a config
/// let mut registry: HashMap<String, RegistryConfig> = HashMap::new();
/// registry.insert(
/// "registry_name".to_owned(),
/// RegistryConfig {
/// host: "example.com".to_owned(),
/// port: 700,
/// tls_files: None,
/// },
/// );
/// let config = EppClientConfig { registry };
///
/// // Create an instance of EppClient, passing the config and the registry you want to connect to
/// let mut client = match EppClient::new(&config, "registry_name").await {
/// Ok(client) => client,
/// Err(e) => panic!("Failed to create EppClient: {}", e)
/// };
///
/// let login = Login::<NoExtension>::new("username", "password", None);
/// client.transact(login, "transaction-id").await.unwrap();
///
/// // Create an DomainTransferQuery instance
/// let domain_transfer_query = DomainTransferQuery::<NoExtension>::new(
/// "eppdev-100.net", "epP4uthd#v"
/// );
///
/// // send it to the registry and receive a response of type DomainTransferQueryResponse
/// let response = client.transact(domain_transfer_query, "transaction-id").await.unwrap();
///
/// println!("{:?}", response);
///
/// let logout = Logout::<NoExtension>::new();
/// client.transact(logout, "transaction-id").await.unwrap();
/// }
/// ```
impl<E: EppExtension> DomainTransferQuery<E> {
pub fn new(name: &str, auth_password: &str) -> DomainTransferQuery<NoExtension> {
DomainTransferQuery {
request: DomainTransferReq {
operation: "query".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: Some(DomainAuthInfo::new(auth_password)),
},
pub fn cancel(name: &str) -> Self {
Self {
operation: "cancel".to_string(),
domain: DomainTransferReqData {
xmlns: XMLNS.to_string(),
name: name.into(),
period: None,
auth_info: None,
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainTransferQuery<F> {
DomainTransferQuery {
request: self.request,
extension: Some(extension),
}
}
}
@ -413,7 +77,7 @@ impl<E: EppExtension> DomainTransferQuery<E> {
// Request
/// Type for elements under the domain &lt;transfer&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainTransferReqData {
/// XML namespace for domain commands
#[serde(rename = "xmlns:domain")]
@ -431,12 +95,11 @@ pub struct DomainTransferReqData {
auth_info: Option<DomainAuthInfo>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "transfer")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;transfer&gt; command for domains
pub struct DomainTransferReq {
pub struct DomainTransfer {
/// The transfer operation to perform indicated by the 'op' attr
/// The values are one of transfer, approve, reject, cancel, or query
/// The values are one of transfer or query
#[serde(rename = "op")]
operation: String,
/// The data under the &lt;transfer&gt; tag in the transfer request
@ -447,11 +110,8 @@ pub struct DomainTransferReq {
// Response
/// Type that represents the &lt;trnData&gt; tag for domain transfer response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainTransferResponseData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// The domain name
pub name: StringValue,
/// The domain transfer status
@ -475,7 +135,7 @@ pub struct DomainTransferResponseData {
}
/// Type that represents the &lt;resData&gt; tag for domain transfer response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct DomainTransferResponse {
/// Data under the &lt;trnData&gt; tag
#[serde(rename = "trnData")]

View File

@ -1,76 +1,52 @@
//! Types for EPP domain check request
use epp_client_macros::*;
//!
use crate::{
common::{
DomainAuthInfo, DomainContact, DomainStatus, ElementName, HostList, NoExtension,
StringValue,
},
request::{EppExtension, Transaction},
common::{DomainAuthInfo, DomainContact, DomainStatus, HostList, NoExtension, StringValue},
request::{Command, Transaction},
};
use super::XMLNS;
use crate::response::ResponseStatus;
use serde::{Deserialize, Serialize};
use serde::Serialize;
#[derive(Debug)]
pub struct DomainUpdate<E> {
request: DomainUpdateRequest,
extension: Option<E>,
impl Transaction<NoExtension> for DomainUpdate {}
impl Command for DomainUpdate {
type Response = ();
const COMMAND: &'static str = "update";
}
impl<E: EppExtension> Transaction<E> for DomainUpdate<E> {
type Input = DomainUpdateRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> DomainUpdate<E> {
pub fn new(name: &str) -> DomainUpdate<NoExtension> {
DomainUpdate {
request: DomainUpdateRequest {
domain: DomainUpdateRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
add: None,
remove: None,
change_info: None,
},
impl DomainUpdate {
pub fn new(name: &str) -> Self {
Self {
domain: DomainUpdateRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
add: None,
remove: None,
change_info: None,
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> DomainUpdate<F> {
DomainUpdate {
request: self.request,
extension: Some(extension),
}
}
/// Sets the data for the &lt;chg&gt; tag
pub fn info(&mut self, info: DomainChangeInfo) {
self.request.domain.change_info = Some(info);
self.domain.change_info = Some(info);
}
/// Sets the data for the &lt;add&gt; tag
pub fn add(&mut self, add: DomainAddRemove) {
self.request.domain.add = Some(add);
self.domain.add = Some(add);
}
/// Sets the data for the &lt;rem&gt; tag
pub fn remove(&mut self, remove: DomainAddRemove) {
self.request.domain.remove = Some(remove);
self.domain.remove = Some(remove);
}
}
/// Type for elements under the &lt;chg&gt; tag for domain update
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainChangeInfo {
/// The new registrant contact for the domain
#[serde(rename = "domain:registrant", alias = "update")]
@ -81,7 +57,7 @@ pub struct DomainChangeInfo {
}
/// Type for elements under the &lt;add&gt; and &lt;rem&gt; tags for domain update
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainAddRemove {
/// The list of nameservers to add or remove
/// Type T can be either a `HostObjList` or `HostAttrList`
@ -96,7 +72,7 @@ pub struct DomainAddRemove {
}
/// Type for elements under the &lt;update&gt; tag for domain update
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct DomainUpdateRequestData {
/// XML namespace for domain commands
#[serde(rename = "xmlns:domain", alias = "xmlns")]
@ -117,10 +93,9 @@ pub struct DomainUpdateRequestData {
pub change_info: Option<DomainChangeInfo>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;update&gt; command for domains
pub struct DomainUpdateRequest {
pub struct DomainUpdate {
#[serde(rename = "domain:update", alias = "update")]
pub domain: DomainUpdateRequestData,
}

View File

@ -3,15 +3,20 @@
use std::fmt;
use chrono::FixedOffset;
use serde::{Deserialize, Serialize};
use serde::Serialize;
use crate::{
common::{NoExtension, StringValue},
request::EppExtension,
};
use crate::common::{NoExtension, StringValue};
use crate::domain::update::DomainUpdate;
use crate::request::{Extension, Transaction};
pub const XMLNS: &str = "http://www.verisign.com/epp/sync-1.0";
impl Transaction<Update> for DomainUpdate {}
impl Extension for Update {
type Response = NoExtension;
}
#[derive(PartialEq, Debug)]
pub struct GMonthDay {
pub month: u8,
@ -65,18 +70,13 @@ impl Update {
}
}
impl EppExtension for Update {
type Response = NoExtension;
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename = "extension")]
#[derive(Debug, Serialize)]
pub struct Update {
#[serde(rename = "sync:update")]
pub data: UpdateData,
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;consolidate&gt; extension
pub struct UpdateData {
/// XML namespace for the consolidate extension

View File

@ -2,10 +2,14 @@
use serde::{Deserialize, Serialize};
use crate::{common::StringValue, request::EppExtension};
use crate::common::StringValue;
use crate::domain::check::DomainCheck;
use crate::request::{Extension, Transaction};
pub const XMLNS: &str = "http://www.verisign-grs.com/epp/namestoreExt-1.1";
impl Transaction<NameStore> for DomainCheck {}
impl NameStore {
/// Create a new RGP restore report request
pub fn new(subproduct: &str) -> NameStore {
@ -18,7 +22,7 @@ impl NameStore {
}
}
impl EppExtension for NameStore {
impl Extension for NameStore {
type Response = NameStore;
}

View File

@ -1,14 +1,15 @@
//! Types for EPP RGP restore report
use epp_client_macros::*;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::EppExtension;
use crate::common::{NoExtension, StringValue};
use crate::domain::update::DomainUpdate;
use crate::request::{Extension, Transaction};
use chrono::{DateTime, SecondsFormat, Utc};
use serde::{Deserialize, Serialize};
use serde::Serialize;
use super::{Update, XMLNS};
impl Transaction<Update<RgpRestoreReport>> for DomainUpdate {}
impl RgpRestoreReport {
/// Create a new RGP restore report request
pub fn new(
@ -44,12 +45,12 @@ impl RgpRestoreReport {
}
}
impl EppExtension for Update<RgpRestoreReport> {
impl Extension for Update<RgpRestoreReport> {
type Response = NoExtension;
}
/// Type corresponding to the &lt;report&gt; section in the EPP rgp restore extension
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct RgpRestoreReportSectionData {
/// The pre-delete registration date
#[serde(rename = "rgp:preData", alias = "preData")]
@ -75,7 +76,7 @@ pub struct RgpRestoreReportSectionData {
}
/// Type corresponding to the &lt;restore&gt; section in the rgp restore extension
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct RgpRestoreReportSection {
/// The value of the op attribute for the &lt;restore&gt; tag
op: String,
@ -84,8 +85,7 @@ pub struct RgpRestoreReportSection {
report: RgpRestoreReportSectionData,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "rgp:update")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;check&gt; command for domains
pub struct RgpRestoreReport {
/// XML namespace for the RGP restore extension

View File

@ -1,30 +1,32 @@
//! Types for EPP RGP restore request
use epp_client_macros::*;
use crate::common::ElementName;
use crate::request::EppExtension;
use crate::{
domain::{info::DomainInfo, update::DomainUpdate},
request::{Extension, Transaction},
};
use serde::{Deserialize, Serialize};
use super::{Update, XMLNS};
impl EppExtension for Update<RgpRestoreRequest> {
impl Transaction<Update<RgpRestoreRequest>> for DomainUpdate {}
impl Transaction<Update<RgpRestoreRequest>> for DomainInfo {}
impl Extension for Update<RgpRestoreRequest> {
type Response = Update<RgpRequestResponse>;
}
// Request
/// Type corresponding to the &lt;restore&gt; tag for an rgp restore request
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct RgpRestoreRequestData {
/// The value of the op attribute in the &lt;restore&gt; tag
pub op: String,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "rgp:update")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;check&gt; command for domains
pub struct RgpRestoreRequest {
/// XML namespace for the RGP restore extension
@ -49,20 +51,17 @@ impl Default for RgpRestoreRequest {
// Response
/// Type that represents the &lt;rgpStatus&gt; tag for domain rgp restore request response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct RgpStatus {
/// The domain RGP status
#[serde(rename = "s")]
pub status: String,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[derive(Deserialize, Debug)]
#[serde(rename = "upData")]
#[element_name(name = "upData")]
/// Type that represents the &lt;resData&gt; tag for domain transfer response
pub struct RgpRequestResponse {
#[serde(rename = "xmlns:rgp")]
xmlns: String,
/// Data under the &lt;rgpStatus&gt; tag
#[serde(rename = "rgpStatus")]
pub rgp_status: Vec<RgpStatus>,

View File

@ -1,9 +1,8 @@
use std::fmt::Debug;
use epp_client_macros::ElementName;
use serde::{Deserialize, Deserializer, Serialize};
use crate::common::{ElementName, Options, ServiceExtension, Services, StringValue, EPP_XMLNS};
use crate::common::{Options, ServiceExtension, Services, StringValue, EPP_XMLNS};
use crate::xml::EppXml;
// Request
@ -278,9 +277,8 @@ pub struct Dcp {
pub expiry: Option<Expiry>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "lowercase")]
#[element_name(name = "greeting")]
/// Type corresponding to the <greeting> tag in the EPP greeting XML
pub struct Greeting {
/// The service ID

View File

@ -2,47 +2,27 @@
use std::fmt::Debug;
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct HostCheck<E> {
request: HostCheckRequest,
extension: Option<E>,
impl Transaction<NoExtension> for HostCheck {}
impl Command for HostCheck {
type Response = HostCheckResponse;
const COMMAND: &'static str = "check";
}
impl<E: EppExtension> Transaction<E> for HostCheck<E> {
type Input = HostCheckRequest;
type Output = HostCheckResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> HostCheck<E> {
pub fn new(hosts: &[&str]) -> HostCheck<NoExtension> {
impl HostCheck {
pub fn new(hosts: &[&str]) -> Self {
let hosts = hosts.iter().map(|&d| d.into()).collect();
HostCheck {
request: HostCheckRequest {
list: HostList {
xmlns: XMLNS.to_string(),
hosts,
},
Self {
list: HostList {
xmlns: XMLNS.to_string(),
hosts,
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> HostCheck<F> {
HostCheck {
request: self.request,
extension: Some(extension),
}
}
}
@ -50,7 +30,7 @@ impl<E: EppExtension> HostCheck<E> {
// Request
/// Type for data under the host &lt;check&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct HostList {
/// XML namespace for host commands
#[serde(rename = "xmlns:host", alias = "xmlns")]
@ -60,10 +40,9 @@ pub struct HostList {
pub hosts: Vec<StringValue>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "check")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;check&gt; command for hosts
pub struct HostCheckRequest {
pub struct HostCheck {
/// The instance holding the list of hosts to be checked
#[serde(rename = "host:check", alias = "check")]
list: HostList,
@ -72,7 +51,7 @@ pub struct HostCheckRequest {
// Response
/// Type that represents the &lt;name&gt; tag for host check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostAvailable {
/// The host name
#[serde(rename = "$value")]
@ -83,7 +62,7 @@ pub struct HostAvailable {
}
/// Type that represents the &lt;cd&gt; tag for host check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostCheckDataItem {
/// Data under the &lt;name&gt; tag
#[serde(rename = "name")]
@ -93,18 +72,15 @@ pub struct HostCheckDataItem {
}
/// Type that represents the &lt;chkData&gt; tag for host check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostCheckData {
/// XML namespace for host response data
#[serde(rename = "xmlns:host")]
xmlns: String,
/// Data under the &lt;cd&gt; tag
#[serde(rename = "cd")]
pub host_list: Vec<HostCheckDataItem>,
}
/// Type that represents the &lt;resData&gt; tag for host check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostCheckResponse {
/// Data under the &lt;chkData&gt; tag
#[serde(rename = "chkData")]

View File

@ -1,45 +1,25 @@
//! Types for EPP host create request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, HostAddr, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{HostAddr, NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct HostCreate<E> {
request: HostCreateRequest,
extension: Option<E>,
impl Transaction<NoExtension> for HostCreate {}
impl Command for HostCreate {
type Response = HostCreateResponse;
const COMMAND: &'static str = "create";
}
impl<E: EppExtension> Transaction<E> for HostCreate<E> {
type Input = HostCreateRequest;
type Output = HostCreateResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> HostCreate<E> {
pub fn new(host: &str, addresses: Vec<HostAddr>) -> HostCreate<NoExtension> {
HostCreate {
request: HostCreateRequest {
host: HostCreateRequestData {
xmlns: XMLNS.to_string(),
name: host.into(),
addresses: Some(addresses),
},
impl HostCreate {
pub fn new(host: &str, addresses: Vec<HostAddr>) -> Self {
Self {
host: HostCreateRequestData {
xmlns: XMLNS.to_string(),
name: host.into(),
addresses: Some(addresses),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> HostCreate<F> {
HostCreate {
request: self.request,
extension: Some(extension),
}
}
}
@ -47,7 +27,7 @@ impl<E: EppExtension> HostCreate<E> {
// Request
/// Type for data under the host &lt;create&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct HostCreateRequestData {
/// XML namespace for host commands
#[serde(rename = "xmlns:host", alias = "xmlns")]
@ -60,10 +40,9 @@ pub struct HostCreateRequestData {
pub addresses: Option<Vec<HostAddr>>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "create")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;create&gt; command for hosts
pub struct HostCreateRequest {
pub struct HostCreate {
/// The instance holding the data for the host to be created
#[serde(rename = "host:create", alias = "create")]
host: HostCreateRequestData,
@ -72,11 +51,8 @@ pub struct HostCreateRequest {
// Response
/// Type that represents the &lt;creData&gt; tag for host create response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostCreateData {
/// XML namespace for host response data
#[serde(rename = "xmlns:host")]
xmlns: String,
/// The host name
pub name: StringValue,
/// The host creation date
@ -85,7 +61,7 @@ pub struct HostCreateData {
}
/// Type that represents the &lt;resData&gt; tag for host check response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostCreateResponse {
/// Data under the &lt;creData&gt; tag
#[serde(rename = "creData")]

View File

@ -1,51 +1,30 @@
//! Types for EPP host delete request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::response::ResponseStatus;
use serde::{Deserialize, Serialize};
use crate::common::{NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::Serialize;
#[derive(Debug)]
pub struct HostDelete<E> {
request: HostDeleteRequest,
extension: Option<E>,
impl Transaction<NoExtension> for HostDelete {}
impl Command for HostDelete {
type Response = ();
const COMMAND: &'static str = "delete";
}
impl<E: EppExtension> Transaction<E> for HostDelete<E> {
type Input = HostDeleteRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> HostDelete<E> {
pub fn new(name: &str) -> HostDelete<NoExtension> {
HostDelete {
request: HostDeleteRequest {
host: HostDeleteRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
},
impl HostDelete {
pub fn new(name: &str) -> Self {
Self {
host: HostDeleteRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> HostDelete<F> {
HostDelete {
request: self.request,
extension: Some(extension),
}
}
}
/// Type for data under the host &lt;delete&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct HostDeleteRequestData {
/// XML namespace for host commands
#[serde(rename = "xmlns:host", alias = "xmlns")]
@ -55,10 +34,9 @@ pub struct HostDeleteRequestData {
name: StringValue,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "delete")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;delete&gt; command for hosts
pub struct HostDeleteRequest {
pub struct HostDelete {
/// The instance holding the data for the host to be deleted
#[serde(rename = "host:delete", alias = "delete")]
host: HostDeleteRequestData,

View File

@ -1,44 +1,24 @@
//! Types for EPP host info request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, HostAddr, HostStatus, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{HostAddr, HostStatus, NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct HostInfo<E> {
request: HostInfoRequest,
extension: Option<E>,
impl Transaction<NoExtension> for HostInfo {}
impl Command for HostInfo {
type Response = HostInfoResponse;
const COMMAND: &'static str = "info";
}
impl<E: EppExtension> Transaction<E> for HostInfo<E> {
type Input = HostInfoRequest;
type Output = HostInfoResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> HostInfo<E> {
pub fn new(name: &str) -> HostInfo<NoExtension> {
HostInfo {
request: HostInfoRequest {
info: HostInfoRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
},
impl HostInfo {
pub fn new(name: &str) -> Self {
Self {
info: HostInfoRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> HostInfo<F> {
HostInfo {
request: self.request,
extension: Some(extension),
}
}
}
@ -46,7 +26,7 @@ impl<E: EppExtension> HostInfo<E> {
// Request
/// Type for data under the host &lt;info&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct HostInfoRequestData {
/// XML namespace for host commands
#[serde(rename = "xmlns:host", alias = "xmlns")]
@ -56,10 +36,9 @@ pub struct HostInfoRequestData {
name: StringValue,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "info")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;info&gt; command for hosts
pub struct HostInfoRequest {
pub struct HostInfo {
/// The instance holding the data for the host query
#[serde(rename = "host:info", alias = "info")]
info: HostInfoRequestData,
@ -68,11 +47,8 @@ pub struct HostInfoRequest {
// Response
/// Type that represents the &lt;infData&gt; tag for host info response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostInfoResponseData {
/// XML namespace for host response data
#[serde(rename = "xmlns:host")]
xmlns: String,
/// The host name
pub name: StringValue,
/// The host ROID
@ -104,7 +80,7 @@ pub struct HostInfoResponseData {
}
/// Type that represents the &lt;resData&gt; tag for host info response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct HostInfoResponse {
/// Data under the &lt;infData&gt; tag
#[serde(rename = "infData")]

View File

@ -1,69 +1,48 @@
//! Types for EPP host update request
use epp_client_macros::*;
use super::XMLNS;
use crate::common::{ElementName, HostAddr, HostStatus, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::response::ResponseStatus;
use serde::{Deserialize, Serialize};
use crate::common::{HostAddr, HostStatus, NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::Serialize;
#[derive(Debug)]
pub struct HostUpdate<E> {
request: HostUpdateRequest,
extension: Option<E>,
impl Transaction<NoExtension> for HostUpdate {}
impl Command for HostUpdate {
type Response = ();
const COMMAND: &'static str = "update";
}
impl<E: EppExtension> Transaction<E> for HostUpdate<E> {
type Input = HostUpdateRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> HostUpdate<E> {
pub fn new(name: &str) -> HostUpdate<NoExtension> {
HostUpdate {
request: HostUpdateRequest {
host: HostUpdateRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
add: None,
remove: None,
change_info: None,
},
impl HostUpdate {
pub fn new(name: &str) -> Self {
Self {
host: HostUpdateRequestData {
xmlns: XMLNS.to_string(),
name: name.into(),
add: None,
remove: None,
change_info: None,
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> HostUpdate<F> {
HostUpdate {
request: self.request,
extension: Some(extension),
}
}
/// Sets the data for the &lt;chg&gt; element of the host update
pub fn info(&mut self, info: HostChangeInfo) {
self.request.host.change_info = Some(info);
self.host.change_info = Some(info);
}
/// Sets the data for the &lt;add&gt; element of the host update
pub fn add(&mut self, add: HostAddRemove) {
self.request.host.add = Some(add);
self.host.add = Some(add);
}
/// Sets the data for the &lt;rem&gt; element of the host update
pub fn remove(&mut self, remove: HostAddRemove) {
self.request.host.remove = Some(remove);
self.host.remove = Some(remove);
}
}
/// Type for data under the &lt;chg&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct HostChangeInfo {
/// The new name for the host
#[serde(rename = "host:name", alias = "name")]
@ -71,7 +50,7 @@ pub struct HostChangeInfo {
}
/// Type for data under the &lt;add&gt; and &lt;rem&gt; tags
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct HostAddRemove {
/// The IP addresses to be added to or removed from the host
#[serde(rename = "host:addr", alias = "addr")]
@ -82,7 +61,7 @@ pub struct HostAddRemove {
}
/// Type for data under the host &lt;update&gt; tag
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Debug)]
pub struct HostUpdateRequestData {
/// XML namespace for host commands
#[serde(rename = "xmlns:host", alias = "xmlns")]
@ -101,10 +80,9 @@ pub struct HostUpdateRequestData {
change_info: Option<HostChangeInfo>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;update&gt; command for hosts
pub struct HostUpdateRequest {
pub struct HostUpdate {
/// The instance holding the data for the host to be updated
#[serde(rename = "host:update", alias = "update")]
host: HostUpdateRequestData,

View File

@ -69,12 +69,12 @@
//! Err(e) => panic!("Failed to create EppClient: {}", e)
//! };
//!
//! let login = Login::<NoExtension>::new("username", "password", None);
//! let login = Login::new("username", "password", None);
//! client.transact(login, "transaction-id").await.unwrap();
//!
//! // Make a domain check call, which returns an object of type EppDomainCheckResponse
//! // that contains the result of the call
//! let domain_check = DomainCheck::<NoExtension>::new(
//! let domain_check = DomainCheck::new(
//! vec!["eppdev.com", "eppdev.net"],
//! );
//!
@ -86,8 +86,7 @@
//! .for_each(|chk| println!("Domain: {}, Available: {}", chk.domain.name, chk.domain.available));
//!
//! // Close the connection
//! let logout = Logout::<NoExtension>::new();
//! client.transact(logout, "transaction-id").await.unwrap();
//! client.transact(Logout, "transaction-id").await.unwrap();
//! }
//! ```
//!

View File

@ -1,81 +1,18 @@
use std::fmt::Debug;
use epp_client_macros::ElementName;
use serde::{Deserialize, Serialize};
use crate::{
common::{ElementName, NoExtension, Options, ServiceExtension, Services, StringValue},
common::{NoExtension, Options, ServiceExtension, Services, StringValue},
contact, domain, host,
request::{EppExtension, Transaction, EPP_LANG, EPP_VERSION},
response::ResponseStatus,
request::{Command, Transaction, EPP_LANG, EPP_VERSION},
};
#[derive(Debug)]
pub struct Login<E> {
request: LoginRequest,
extension: Option<E>,
}
impl Transaction<NoExtension> for Login {}
impl<E: EppExtension> Transaction<E> for Login<E> {
type Input = LoginRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> Login<E> {
pub fn new(
username: &str,
password: &str,
ext_uris: Option<Vec<String>>,
) -> Login<NoExtension> {
let ext_uris = ext_uris.map(|uris| uris.iter().map(|u| u.as_str().into()).collect());
Login {
request: LoginRequest {
username: username.into(),
password: password.into(),
options: Options {
version: EPP_VERSION.into(),
lang: EPP_LANG.into(),
},
services: Services {
obj_uris: vec![
host::XMLNS.into(),
contact::XMLNS.into(),
domain::XMLNS.into(),
],
svc_ext: Some(ServiceExtension { ext_uris }),
},
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> Login<F> {
Login {
request: self.request,
extension: Some(extension),
}
}
/// Sets the <options> tag data
pub fn options(&mut self, options: Options) {
self.request.options = options;
}
/// Sets the <svcs> tag data
pub fn services(&mut self, services: Services) {
self.request.services = services;
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "login")]
#[derive(Serialize, Deserialize, Debug, PartialEq)]
/// Type corresponding to the &lt;login&gt; tag in an EPP XML login request
pub struct LoginRequest {
pub struct Login {
/// The username to use for the login
#[serde(rename(serialize = "clID", deserialize = "clID"))]
username: StringValue,
@ -88,3 +25,41 @@ pub struct LoginRequest {
#[serde(rename = "svcs")]
services: Services,
}
impl Login {
pub fn new(username: &str, password: &str, ext_uris: Option<Vec<String>>) -> Self {
let ext_uris = ext_uris.map(|uris| uris.iter().map(|u| u.as_str().into()).collect());
Self {
username: username.into(),
password: password.into(),
options: Options {
version: EPP_VERSION.into(),
lang: EPP_LANG.into(),
},
services: Services {
obj_uris: vec![
host::XMLNS.into(),
contact::XMLNS.into(),
domain::XMLNS.into(),
],
svc_ext: Some(ServiceExtension { ext_uris }),
},
}
}
/// Sets the <options> tag data
pub fn options(&mut self, options: Options) {
self.options = options;
}
/// Sets the <svcs> tag data
pub fn services(&mut self, services: Services) {
self.services = services;
}
}
impl Command for Login {
type Response = ();
const COMMAND: &'static str = "login";
}

View File

@ -1,46 +1,19 @@
use std::fmt::Debug;
use epp_client_macros::ElementName;
use serde::{Deserialize, Serialize};
use crate::{
common::{ElementName, NoExtension},
request::{EppExtension, Transaction},
response::ResponseStatus,
common::NoExtension,
request::{Command, Transaction},
};
#[derive(Debug)]
pub struct Logout<E> {
request: LogoutRequest,
extension: Option<E>,
impl Transaction<NoExtension> for Logout {}
impl Command for Logout {
type Response = ();
const COMMAND: &'static str = "logout";
}
impl<E: EppExtension> Transaction<E> for Logout<E> {
type Input = LogoutRequest;
type Output = ResponseStatus;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> Logout<E> {
pub fn new() -> Logout<NoExtension> {
Logout {
request: LogoutRequest {},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> Logout<F> {
Logout {
request: self.request,
extension: Some(extension),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "logout")]
#[derive(Serialize, Deserialize, Debug, PartialEq)]
/// Type corresponding to the &lt;logout&gt; tag in an EPP XML logout request
pub struct LogoutRequest;
pub struct Logout;

View File

@ -1,49 +1,19 @@
//! Types for EPP message ack request
use epp_client_macros::*;
use crate::common::{ElementName, NoExtension};
use crate::request::{EppExtension, Transaction};
use crate::common::NoExtension;
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct MessageAck<E> {
request: MessageAckRequest,
extension: Option<E>,
impl Transaction<NoExtension> for MessageAck {}
impl Command for MessageAck {
type Response = String;
const COMMAND: &'static str = "poll";
}
impl<E: EppExtension> Transaction<E> for MessageAck<E> {
type Input = MessageAckRequest;
type Output = String;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> MessageAck<E> {
pub fn new(message_id: u32) -> MessageAck<NoExtension> {
MessageAck {
request: MessageAckRequest {
op: "ack".to_string(),
message_id: message_id.to_string(),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> MessageAck<F> {
MessageAck {
request: self.request,
extension: Some(extension),
}
}
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "poll")]
#[derive(Serialize, Deserialize, Debug)]
/// Type for EPP XML &lt;poll&gt; command for message ack
pub struct MessageAckRequest {
pub struct MessageAck {
/// The type of operation to perform
/// The value is "ack" for message acknowledgement
op: String,
@ -51,3 +21,12 @@ pub struct MessageAckRequest {
#[serde(rename = "msgID")]
message_id: String,
}
impl MessageAck {
pub fn new(message_id: u32) -> Self {
Self {
op: "ack".to_string(),
message_id: message_id.to_string(),
}
}
}

View File

@ -1,63 +1,37 @@
//! Types for EPP message poll request
use epp_client_macros::*;
use crate::common::{ElementName, NoExtension, StringValue};
use crate::request::{EppExtension, Transaction};
use crate::common::{NoExtension, StringValue};
use crate::request::{Command, Transaction};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct MessagePoll<E> {
request: MessagePollRequest,
extension: Option<E>,
}
impl Transaction<NoExtension> for MessagePoll {}
impl<E: EppExtension> Transaction<E> for MessagePoll<E> {
type Input = MessagePollRequest;
type Output = MessagePollResponse;
fn into_parts(self) -> (Self::Input, Option<E>) {
(self.request, self.extension)
}
}
impl<E: EppExtension> MessagePoll<E> {
pub fn new() -> MessagePoll<NoExtension> {
MessagePoll {
request: MessagePollRequest {
op: "req".to_string(),
},
extension: None,
}
}
pub fn with_extension<F: EppExtension>(self, extension: F) -> MessagePoll<F> {
MessagePoll {
request: self.request,
extension: Some(extension),
}
}
impl Command for MessagePoll {
type Response = MessagePollResponse;
const COMMAND: &'static str = "poll";
}
// Request
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "poll")]
#[derive(Serialize, Debug)]
/// Type for EPP XML &lt;poll&gt; command for message poll
pub struct MessagePollRequest {
pub struct MessagePoll {
/// The type of operation to perform
/// The value is "req" for message polling
op: String,
}
impl Default for MessagePoll {
fn default() -> Self {
Self {
op: "req".to_owned(),
}
}
}
// Response
/// Type that represents the &lt;trnData&gt; tag for message poll response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct MessageDomainTransferData {
/// XML namespace for message response data
#[serde(rename = "xmlns:domain", alias = "xmlns")]
xmlns: String,
/// The name of the domain under transfer
#[serde(rename = "domain:name", alias = "name")]
pub name: StringValue,
@ -82,7 +56,7 @@ pub struct MessageDomainTransferData {
}
/// Type that represents the &lt;resData&gt; tag for message poll response
#[derive(Serialize, Deserialize, Debug)]
#[derive(Deserialize, Debug)]
pub struct MessagePollResponse {
/// Data under the &lt;trnData&gt; tag
#[serde(rename = "domain:trnData", alias = "trnData")]

View File

@ -1,30 +1,27 @@
//! Types for EPP requests
use serde::{de::DeserializeOwned, ser::SerializeStruct, ser::Serializer, Deserialize, Serialize};
use serde::{de::DeserializeOwned, ser::SerializeStruct, ser::Serializer, Serialize};
use std::fmt::Debug;
use crate::{
common::{ElementName, StringValue, EPP_XMLNS},
common::{StringValue, EPP_XMLNS},
response::{Response, ResponseDocument, ResponseStatus},
xml::EppXml,
};
use epp_client_macros::ElementName;
pub const EPP_VERSION: &str = "1.0";
pub const EPP_LANG: &str = "en";
/// Trait to set correct value for xml tags when tags are being generated from generic types
pub trait Transaction<E: EppExtension>: Sized + Debug {
type Input: ElementName + Serialize + Sized + Debug;
type Output: DeserializeOwned + Debug;
fn into_parts(self) -> (Self::Input, Option<E>);
fn serialize_request(self, client_tr_id: &str) -> Result<String, Box<dyn std::error::Error>> {
let (command, extension) = self.into_parts();
<CommandDocument<Self::Input, E> as EppXml>::serialize(&CommandDocument::new(Command {
command: <Self::Input as ElementName>::ELEMENT,
data: command,
pub trait Transaction<Ext: Extension>: Command + Sized {
fn serialize_request(
self,
extension: Option<Ext>,
client_tr_id: &str,
) -> Result<String, Box<dyn std::error::Error>> {
<CommandDocument<Self, Ext> as EppXml>::serialize(&CommandDocument::new(CommandWrapper {
command: Self::COMMAND,
data: self,
extension,
client_tr_id: client_tr_id.into(),
}))
@ -32,8 +29,9 @@ pub trait Transaction<E: EppExtension>: Sized + Debug {
fn deserialize_response(
epp_xml: &str,
) -> Result<Response<Self::Output, E::Response>, crate::error::Error> {
let rsp = <ResponseDocument<Self::Output, E::Response> as EppXml>::deserialize(epp_xml)?;
) -> Result<Response<Self::Response, Ext::Response>, crate::error::Error> {
let rsp =
<ResponseDocument<Self::Response, Ext::Response> as EppXml>::deserialize(epp_xml)?;
match rsp.data.result.code {
0..=2000 => Ok(rsp.data),
_ => Err(crate::error::Error::EppCommandError(ResponseStatus {
@ -44,25 +42,28 @@ pub trait Transaction<E: EppExtension>: Sized + Debug {
}
}
pub trait EppExtension: Serialize + Sized + Debug {
pub trait Command: Serialize + Debug {
type Response: DeserializeOwned + Debug;
const COMMAND: &'static str;
}
pub trait Extension: Serialize + Debug {
type Response: DeserializeOwned + Debug;
}
#[derive(Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "command")]
#[derive(Debug, PartialEq)]
/// Type corresponding to the &lt;command&gt; tag in an EPP XML request
/// with an &lt;extension&gt; tag
pub struct Command<D, E> {
pub struct CommandWrapper<D, E> {
pub command: &'static str,
/// The instance that will be used to populate the &lt;command&gt; tag
pub data: D,
/// The client TRID
pub extension: Option<E>,
#[serde(rename = "clTRID")]
pub client_tr_id: StringValue,
}
impl<D: Serialize, E: Serialize> Serialize for Command<D, E> {
impl<D: Serialize, E: Serialize> Serialize for CommandWrapper<D, E> {
/// Serializes the generic type T to the proper XML tag (set by the `#[element_name(name = <tagname>)]` attribute) for the request
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@ -76,15 +77,15 @@ impl<D: Serialize, E: Serialize> Serialize for Command<D, E> {
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[derive(Debug, PartialEq, Serialize)]
#[serde(rename = "epp")]
pub struct CommandDocument<D, E> {
xmlns: &'static str,
command: Command<D, E>,
command: CommandWrapper<D, E>,
}
impl<D, E> CommandDocument<D, E> {
pub fn new(command: Command<D, E>) -> Self {
pub fn new(command: CommandWrapper<D, E>) -> Self {
Self {
xmlns: EPP_XMLNS,
command,

View File

@ -1,18 +1,17 @@
//! Types for EPP responses
use epp_client_macros::*;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize};
use std::fmt::Debug;
use crate::common::{ElementName, StringValue};
use crate::common::StringValue;
use crate::xml::EppXml;
/// Type corresponding to the <undef> tag an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]
pub struct Undef;
/// Type corresponding to the <value> tag under <extValue> in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]
pub struct ResultValue {
/// The XML namespace for the <value> tag
#[serde(rename = "xmlns:epp")]
@ -22,7 +21,7 @@ pub struct ResultValue {
}
/// Type corresponding to the <extValue> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]
pub struct ExtValue {
/// Data under the <value> tag
pub value: ResultValue,
@ -31,7 +30,7 @@ pub struct ExtValue {
}
/// Type corresponding to the <result> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]
pub struct EppResult {
/// The result code
pub code: u16,
@ -44,7 +43,7 @@ pub struct EppResult {
}
/// Type corresponding to the <trID> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]
pub struct ResponseTRID {
/// The client TRID
#[serde(rename = "clTRID")]
@ -55,7 +54,7 @@ pub struct ResponseTRID {
}
/// Type corresponding to the <msgQ> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]
pub struct MessageQueue {
/// The message count
pub count: u32,
@ -69,8 +68,7 @@ pub struct MessageQueue {
pub message: Option<StringValue>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[serde(rename_all = "lowercase")]
#[derive(Deserialize, Debug, PartialEq)]
/// Type corresponding to the &lt;response&gt; tag in an EPP response XML
/// containing an &lt;extension&gt; tag
pub struct Response<D, E> {
@ -107,8 +105,7 @@ pub struct ResultDocument {
impl EppXml for ResultDocument {}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "response")]
#[derive(Deserialize, Debug, PartialEq)]
/// Type corresponding to the &lt;response&gt; tag in an EPP response XML
/// without <msgQ> or &lt;resData&gt; sections. Generally used for error handling
pub struct ResponseStatus {
@ -119,7 +116,7 @@ pub struct ResponseStatus {
pub tr_ids: ResponseTRID,
}
impl<T, E: ElementName> Response<T, E> {
impl<T, E> Response<T, E> {
/// Returns the data under the corresponding &lt;resData&gt; from the EPP XML
pub fn res_data(&self) -> Option<&T> {
match &self.res_data {

View File

@ -14,11 +14,7 @@ mod response {
use crate::domain::delete::DomainDelete;
use crate::domain::info::DomainInfo;
use crate::domain::renew::DomainRenew;
use crate::domain::transfer::DomainTransferApprove;
use crate::domain::transfer::DomainTransferCancel;
use crate::domain::transfer::DomainTransferQuery;
use crate::domain::transfer::DomainTransferReject;
use crate::domain::transfer::DomainTransferRequest;
use crate::domain::transfer::DomainTransfer;
use crate::domain::update::DomainUpdate;
use crate::extensions::namestore::NameStore;
use crate::extensions::rgp;
@ -90,7 +86,7 @@ mod response {
#[test]
fn login() {
let xml = get_xml("response/login.xml").unwrap();
let object = Login::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = Login::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -101,7 +97,7 @@ mod response {
#[test]
fn logout() {
let xml = get_xml("response/logout.xml").unwrap();
let object = Logout::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = Logout::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1500);
assert_eq!(
@ -115,7 +111,7 @@ mod response {
#[test]
fn contact_check() {
let xml = get_xml("response/contact/check.xml").unwrap();
let object = ContactCheck::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = ContactCheck::deserialize_response(xml.as_str()).unwrap();
let results = object.res_data().unwrap();
@ -138,7 +134,7 @@ mod response {
#[test]
fn contact_create() {
let xml = get_xml("response/contact/create.xml").unwrap();
let object = ContactCreate::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = ContactCreate::deserialize_response(xml.as_str()).unwrap();
let results = object.res_data().unwrap();
@ -156,7 +152,7 @@ mod response {
#[test]
fn contact_delete() {
let xml = get_xml("response/contact/delete.xml").unwrap();
let object = ContactDelete::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = ContactDelete::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -167,7 +163,7 @@ mod response {
#[test]
fn contact_info() {
let xml = get_xml("response/contact/info.xml").unwrap();
let object = ContactInfo::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = ContactInfo::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
let fax = result.info_data.fax.as_ref().unwrap();
@ -225,7 +221,7 @@ mod response {
#[test]
fn contact_update() {
let xml = get_xml("response/contact/update.xml").unwrap();
let object = ContactUpdate::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = ContactUpdate::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -236,7 +232,8 @@ mod response {
#[test]
fn domain_check() {
let xml = get_xml("response/domain/check.xml").unwrap();
let object = DomainCheck::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object =
<DomainCheck as Transaction<NoExtension>>::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -259,7 +256,7 @@ mod response {
#[test]
fn domain_create() {
let xml = get_xml("response/domain/create.xml").unwrap();
let object = DomainCreate::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainCreate::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -281,7 +278,7 @@ mod response {
#[test]
fn domain_delete() {
let xml = get_xml("response/domain/delete.xml").unwrap();
let object = DomainDelete::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainDelete::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -292,7 +289,8 @@ mod response {
#[test]
fn domain_info() {
let xml = get_xml("response/domain/info.xml").unwrap();
let object = DomainInfo::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object =
<DomainInfo as Transaction<NoExtension>>::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
let auth_info = result.info_data.auth_info.as_ref().unwrap();
@ -349,13 +347,13 @@ mod response {
#[test]
fn domain_info_alt() {
let xml = get_xml("response/domain/info_alt.xml").unwrap();
DomainInfo::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
<DomainInfo as Transaction<NoExtension>>::deserialize_response(xml.as_str()).unwrap();
}
#[test]
fn domain_renew() {
let xml = get_xml("response/domain/renew.xml").unwrap();
let object = DomainRenew::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainRenew::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -373,8 +371,7 @@ mod response {
#[test]
fn domain_transfer_request() {
let xml = get_xml("response/domain/transfer_request.xml").unwrap();
let object =
DomainTransferRequest::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainTransfer::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -403,8 +400,7 @@ mod response {
#[test]
fn domain_transfer_approve() {
let xml = get_xml("response/domain/transfer_approve.xml").unwrap();
let object =
DomainTransferApprove::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainTransfer::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -415,8 +411,7 @@ mod response {
#[test]
fn domain_transfer_reject() {
let xml = get_xml("response/domain/transfer_reject.xml").unwrap();
let object =
DomainTransferReject::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainTransfer::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -427,8 +422,7 @@ mod response {
#[test]
fn domain_transfer_cancel() {
let xml = get_xml("response/domain/transfer_cancel.xml").unwrap();
let object =
DomainTransferCancel::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainTransfer::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -439,8 +433,7 @@ mod response {
#[test]
fn domain_transfer_query() {
let xml = get_xml("response/domain/transfer_query.xml").unwrap();
let object =
DomainTransferQuery::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = DomainTransfer::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -466,7 +459,8 @@ mod response {
#[test]
fn domain_update() {
let xml = get_xml("response/domain/update.xml").unwrap();
let object = DomainUpdate::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object =
<DomainUpdate as Transaction<NoExtension>>::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -477,7 +471,7 @@ mod response {
#[test]
fn host_check() {
let xml = get_xml("response/host/check.xml").unwrap();
let object = HostCheck::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = HostCheck::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -500,7 +494,7 @@ mod response {
#[test]
fn host_create() {
let xml = get_xml("response/host/create.xml").unwrap();
let object = HostCreate::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = HostCreate::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -518,7 +512,7 @@ mod response {
#[test]
fn host_info() {
let xml = get_xml("response/host/info.xml").unwrap();
let object = HostInfo::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = HostInfo::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
@ -561,7 +555,7 @@ mod response {
#[test]
fn host_update() {
let xml = get_xml("response/host/update.xml").unwrap();
let object = HostUpdate::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = HostUpdate::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -572,7 +566,7 @@ mod response {
#[test]
fn host_delete() {
let xml = get_xml("response/host/delete.xml").unwrap();
let object = HostDelete::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = HostDelete::deserialize_response(xml.as_str()).unwrap();
assert_eq!(object.result.code, 1000);
assert_eq!(object.result.message, SUCCESS_MSG.into());
@ -583,7 +577,7 @@ mod response {
#[test]
fn message_poll() {
let xml = get_xml("response/message/poll.xml").unwrap();
let object = MessagePoll::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = MessagePoll::deserialize_response(xml.as_str()).unwrap();
let result = object.res_data().unwrap();
let msg = object.message_queue().unwrap();
@ -623,7 +617,7 @@ mod response {
#[test]
fn message_ack() {
let xml = get_xml("response/message/ack.xml").unwrap();
let object = MessageAck::<NoExtension>::deserialize_response(xml.as_str()).unwrap();
let object = MessageAck::deserialize_response(xml.as_str()).unwrap();
let msg = object.message_queue().unwrap();
@ -638,7 +632,7 @@ mod response {
fn rgp_restore_response() {
let xml = get_xml("response/extensions/rgp_restore.xml").unwrap();
let object =
DomainUpdate::<rgp::Update<rgp::request::RgpRestoreRequest>>::deserialize_response(
<DomainUpdate as Transaction<rgp::Update<rgp::request::RgpRestoreRequest>>>::deserialize_response(
xml.as_str(),
)
.unwrap();
@ -655,7 +649,7 @@ mod response {
fn rgp_restore_domain_info_response() {
let xml = get_xml("response/extensions/domain_info_rgp.xml").unwrap();
let object =
DomainInfo::<rgp::Update<rgp::request::RgpRestoreRequest>>::deserialize_response(
<DomainInfo as Transaction<rgp::Update<rgp::request::RgpRestoreRequest>>>::deserialize_response(
xml.as_str(),
)
.unwrap();
@ -670,7 +664,8 @@ mod response {
fn namestore() {
let xml = get_xml("response/extensions/namestore.xml").unwrap();
let object = DomainCheck::<NameStore>::deserialize_response(xml.as_str()).unwrap();
let object =
<DomainCheck as Transaction<NameStore>>::deserialize_response(xml.as_str()).unwrap();
let ext = object.extension.unwrap();

View File

@ -21,11 +21,7 @@ mod request {
use crate::domain::delete::DomainDelete;
use crate::domain::info::DomainInfo;
use crate::domain::renew::DomainRenew;
use crate::domain::transfer::DomainTransferApprove;
use crate::domain::transfer::DomainTransferCancel;
use crate::domain::transfer::DomainTransferQuery;
use crate::domain::transfer::DomainTransferReject;
use crate::domain::transfer::DomainTransferRequest;
use crate::domain::transfer::DomainTransfer;
use crate::domain::update::DomainAddRemove;
use crate::domain::update::DomainChangeInfo;
use crate::domain::update::DomainUpdate;
@ -65,8 +61,8 @@ mod request {
]);
let xml = get_xml("request/login.xml").unwrap();
let object = Login::<NoExtension>::new("username", "password", ext_uris);
let serialized = object.serialize_request(CLTRID).unwrap();
let object = Login::new("username", "password", ext_uris);
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -74,8 +70,8 @@ mod request {
#[test]
fn logout() {
let xml = get_xml("request/logout.xml").unwrap();
let object = Logout::<NoExtension>::new();
let serialized = object.serialize_request(CLTRID).unwrap();
let object = Logout;
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -83,8 +79,8 @@ mod request {
#[test]
fn contact_check() {
let xml = get_xml("request/contact/check.xml").unwrap();
let object = ContactCheck::<NoExtension>::new(&["eppdev-contact-1", "eppdev-contact-2"]);
let serialized = object.serialize_request(CLTRID).unwrap();
let object = ContactCheck::new(&["eppdev-contact-1", "eppdev-contact-2"]);
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -101,7 +97,7 @@ mod request {
let mut fax = Phone::new("+33.86698799");
fax.set_extension("677");
let mut object = ContactCreate::<NoExtension>::new(
let mut object = ContactCreate::new(
"eppdev-contact-3",
"contact@eppdev.net",
postal_info,
@ -110,7 +106,7 @@ mod request {
);
object.set_fax(fax);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -119,9 +115,9 @@ mod request {
fn contact_info() {
let xml = get_xml("request/contact/info.xml").unwrap();
let object = ContactInfo::<NoExtension>::new("eppdev-contact-3", "eppdev-387323");
let object = ContactInfo::new("eppdev-contact-3", "eppdev-387323");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -130,7 +126,7 @@ mod request {
fn contact_update() {
let xml = get_xml("request/contact/update.xml").unwrap();
let mut object = ContactUpdate::<NoExtension>::new("eppdev-contact-3");
let mut object = ContactUpdate::new("eppdev-contact-3");
let street = &["58", "Orchid Road"];
let address = Address::new(street, "Paris", "Paris", "392374", "FR".parse().unwrap());
@ -147,7 +143,7 @@ mod request {
}];
object.remove(remove_statuses);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -156,9 +152,9 @@ mod request {
fn contact_delete() {
let xml = get_xml("request/contact/delete.xml").unwrap();
let object = ContactDelete::<NoExtension>::new("eppdev-contact-3");
let object = ContactDelete::new("eppdev-contact-3");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -167,9 +163,11 @@ mod request {
fn domain_check() {
let xml = get_xml("request/domain/check.xml").unwrap();
let object = DomainCheck::<NoExtension>::new(vec!["eppdev.com", "eppdev.net"]);
let object = DomainCheck::new(vec!["eppdev.com", "eppdev.net"]);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized =
<DomainCheck as Transaction<NoExtension>>::serialize_request(object, None, CLTRID)
.unwrap();
assert_eq!(xml, serialized);
}
@ -193,7 +191,7 @@ mod request {
},
];
let object = DomainCreate::<NoExtension>::new(
let object = DomainCreate::new(
"eppdev-1.com",
1,
None,
@ -202,7 +200,7 @@ mod request {
Some(contacts),
);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -230,7 +228,7 @@ mod request {
hosts: vec!["ns1.test.com".into(), "ns2.test.com".into()],
}));
let object = DomainCreate::<NoExtension>::new(
let object = DomainCreate::new(
"eppdev-1.com",
1,
ns,
@ -239,7 +237,7 @@ mod request {
Some(contacts),
);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -279,7 +277,7 @@ mod request {
],
});
let object = DomainCreate::<NoExtension>::new(
let object = DomainCreate::new(
"eppdev-2.com",
1,
Some(host_attr),
@ -288,7 +286,7 @@ mod request {
Some(contacts),
);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -297,9 +295,11 @@ mod request {
fn domain_info() {
let xml = get_xml("request/domain/info.xml").unwrap();
let object = DomainInfo::<NoExtension>::new("eppdev.com", Some("2fooBAR"));
let object = DomainInfo::new("eppdev.com", Some("2fooBAR"));
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized =
<DomainInfo as Transaction<NoExtension>>::serialize_request(object, None, CLTRID)
.unwrap();
assert_eq!(xml, serialized);
}
@ -308,7 +308,7 @@ mod request {
fn domain_update() {
let xml = get_xml("request/domain/update.xml").unwrap();
let mut object = DomainUpdate::<NoExtension>::new("eppdev.com");
let mut object = DomainUpdate::new("eppdev.com");
let add = DomainAddRemove {
ns: None,
@ -336,7 +336,9 @@ mod request {
object.remove(remove);
object.info(change_info);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized =
<DomainUpdate as Transaction<NoExtension>>::serialize_request(object, None, CLTRID)
.unwrap();
assert_eq!(xml, serialized);
}
@ -345,9 +347,9 @@ mod request {
fn domain_delete() {
let xml = get_xml("request/domain/delete.xml").unwrap();
let object = DomainDelete::<NoExtension>::new("eppdev.com");
let object = DomainDelete::new("eppdev.com");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -357,9 +359,9 @@ mod request {
let xml = get_xml("request/domain/renew.xml").unwrap();
let exp_date = NaiveDate::from_ymd(2022, 7, 23);
let object = DomainRenew::<NoExtension>::new("eppdev.com", exp_date, 1);
let object = DomainRenew::new("eppdev.com", exp_date, 1);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -368,10 +370,9 @@ mod request {
fn domain_transfer_request() {
let xml = get_xml("request/domain/transfer_request.xml").unwrap();
let object =
DomainTransferRequest::<NoExtension>::new("testing.com", Some(1), "epP4uthd#v");
let object = DomainTransfer::new("testing.com", Some(1), "epP4uthd#v");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -380,9 +381,9 @@ mod request {
fn domain_transfer_approve() {
let xml = get_xml("request/domain/transfer_approve.xml").unwrap();
let object = DomainTransferApprove::<NoExtension>::new("testing.com");
let object = DomainTransfer::approve("testing.com");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -391,9 +392,9 @@ mod request {
fn domain_transfer_reject() {
let xml = get_xml("request/domain/transfer_reject.xml").unwrap();
let object = DomainTransferReject::<NoExtension>::new("testing.com");
let object = DomainTransfer::reject("testing.com");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -402,9 +403,9 @@ mod request {
fn domain_transfer_cancel() {
let xml = get_xml("request/domain/transfer_cancel.xml").unwrap();
let object = DomainTransferCancel::<NoExtension>::new("testing.com");
let object = DomainTransfer::cancel("testing.com");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -413,9 +414,9 @@ mod request {
fn domain_transfer_query() {
let xml = get_xml("request/domain/transfer_query.xml").unwrap();
let object = DomainTransferQuery::<NoExtension>::new("testing.com", "epP4uthd#v");
let object = DomainTransfer::query("testing.com", "epP4uthd#v");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -424,9 +425,9 @@ mod request {
fn host_check() {
let xml = get_xml("request/host/check.xml").unwrap();
let object = HostCheck::<NoExtension>::new(&["ns1.eppdev-1.com", "host1.eppdev-1.com"]);
let object = HostCheck::new(&["ns1.eppdev-1.com", "host1.eppdev-1.com"]);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -440,9 +441,9 @@ mod request {
HostAddr::new("v6", "2404:6800:4001:801::200e"),
];
let object = HostCreate::<NoExtension>::new("host1.eppdev-1.com", addresses);
let object = HostCreate::new("host1.eppdev-1.com", addresses);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -451,9 +452,9 @@ mod request {
fn host_info() {
let xml = get_xml("request/host/info.xml").unwrap();
let object = HostInfo::<NoExtension>::new("ns1.eppdev-1.com");
let object = HostInfo::new("ns1.eppdev-1.com");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -476,7 +477,7 @@ mod request {
}]),
};
let mut object = HostUpdate::<NoExtension>::new("host1.eppdev-1.com");
let mut object = HostUpdate::new("host1.eppdev-1.com");
object.add(add);
object.remove(remove);
@ -484,7 +485,7 @@ mod request {
name: "host2.eppdev-1.com".into(),
});
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -493,9 +494,9 @@ mod request {
fn host_delete() {
let xml = get_xml("request/host/delete.xml").unwrap();
let object = HostDelete::<NoExtension>::new("ns1.eppdev-1.com");
let object = HostDelete::new("ns1.eppdev-1.com");
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -504,9 +505,9 @@ mod request {
fn message_poll() {
let xml = get_xml("request/message/poll.xml").unwrap();
let object = MessagePoll::<NoExtension>::new();
let object = MessagePoll::default();
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -515,9 +516,9 @@ mod request {
fn message_ack() {
let xml = get_xml("request/message/ack.xml").unwrap();
let object = MessageAck::<NoExtension>::new(12345);
let object = MessageAck::new(12345);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = object.serialize_request(None, CLTRID).unwrap();
assert_eq!(xml, serialized);
}
@ -530,8 +531,7 @@ mod request {
data: RgpRestoreRequest::default(),
};
let mut object = DomainUpdate::<rgp::Update<RgpRestoreRequest>>::new("eppdev.com")
.with_extension(domain_restore_request);
let mut object = DomainUpdate::new("eppdev.com");
let change_info = DomainChangeInfo {
registrant: None,
@ -540,7 +540,13 @@ mod request {
object.info(change_info);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized =
<DomainUpdate as Transaction<rgp::Update<RgpRestoreRequest>>>::serialize_request(
object,
Some(domain_restore_request),
CLTRID,
)
.unwrap();
assert_eq!(xml, serialized);
}
@ -574,17 +580,19 @@ mod request {
),
};
let mut object = DomainUpdate::<rgp::Update<RgpRestoreReport>>::new("eppdev.com")
.with_extension(domain_restore_report);
let change_info = DomainChangeInfo {
let mut object = DomainUpdate::new("eppdev.com");
object.info(DomainChangeInfo {
registrant: None,
auth_info: None,
};
});
object.info(change_info);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized =
<DomainUpdate as Transaction<rgp::Update<RgpRestoreReport>>>::serialize_request(
object,
Some(domain_restore_report),
CLTRID,
)
.unwrap();
assert_eq!(xml, serialized);
}
@ -595,11 +603,14 @@ mod request {
let namestore_ext = NameStore::new("com");
let object =
DomainCheck::<NameStore>::new(vec!["example1.com", "example2.com", "example3.com"])
.with_extension(namestore_ext);
let object = DomainCheck::new(vec!["example1.com", "example2.com", "example3.com"]);
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = <DomainCheck as Transaction<NameStore>>::serialize_request(
object,
Some(namestore_ext),
CLTRID,
)
.unwrap();
assert_eq!(xml, serialized);
}
@ -612,15 +623,19 @@ mod request {
let consolidate_ext = consolidate::Update::new(exp);
let mut object =
DomainUpdate::<consolidate::Update>::new("eppdev.com").with_extension(consolidate_ext);
let mut object = DomainUpdate::new("eppdev.com");
object.info(DomainChangeInfo {
registrant: None,
auth_info: None,
});
let serialized = object.serialize_request(CLTRID).unwrap();
let serialized = <DomainUpdate as Transaction<consolidate::Update>>::serialize_request(
object,
Some(consolidate_ext),
CLTRID,
)
.unwrap();
assert_eq!(xml, serialized);
}