added doc comments for request types

This commit is contained in:
Ritesh Chitlangi 2021-07-25 22:34:01 +08:00
parent 28f744ea26
commit 198c92c40f
29 changed files with 436 additions and 96 deletions

View File

@ -15,6 +15,7 @@ bytes = "1"
chrono = "0.4" chrono = "0.4"
confy = "0.4" confy = "0.4"
futures = "0.3" futures = "0.3"
env_logger = "0.9"
log = "0.4" log = "0.4"
lazy_static = "1.4" lazy_static = "1.4"
quick-xml = { version = "0.22", features = [ "serialize" ] } quick-xml = { version = "0.22", features = [ "serialize" ] }

View File

@ -1,5 +1,6 @@
use std::{error::Error, time::SystemTime}; use std::{error::Error, time::SystemTime};
use chrono::NaiveDate; use chrono::NaiveDate;
use env_logger;
use epp_client::EppClient; use epp_client::EppClient;
use epp_client::epp::object::{StringValueTrait}; use epp_client::epp::object::{StringValueTrait};
@ -41,8 +42,6 @@ async fn create_contact(client: &mut EppClient) {
let mut contact_create = EppContactCreate::new("eppdev-contact-3", "contact@eppdev.net", postal_info, voice, "eppdev-387323", gen_client_tr_id("eppdev").unwrap().as_str()); let mut contact_create = EppContactCreate::new("eppdev-contact-3", "contact@eppdev.net", postal_info, voice, "eppdev-387323", gen_client_tr_id("eppdev").unwrap().as_str());
contact_create.set_fax(fax); contact_create.set_fax(fax);
// println!("xml: {}", contact_create.serialize().unwrap());
client.transact::<_, EppContactCreateResponse>(&contact_create).await.unwrap(); client.transact::<_, EppContactCreateResponse>(&contact_create).await.unwrap();
} }
@ -56,8 +55,6 @@ async fn update_contact(client: &mut EppClient) {
let add_statuses = vec![ContactStatus { status: "clientTransferProhibited".to_string() }]; let add_statuses = vec![ContactStatus { status: "clientTransferProhibited".to_string() }];
contact_update.remove_statuses(add_statuses); contact_update.remove_statuses(add_statuses);
// println!("{}", contact_update.serialize().unwrap());
client.transact::<_, EppContactUpdateResponse>(&contact_update).await.unwrap(); client.transact::<_, EppContactUpdateResponse>(&contact_update).await.unwrap();
} }
@ -92,8 +89,6 @@ async fn create_domain(client: &mut EppClient) {
let domain_create = EppDomainCreate::new("eppdev-1.com", 1, "eppdev-contact-2", "epP4uthd#v", contacts, gen_client_tr_id("eppdev").unwrap().as_str()); let domain_create = EppDomainCreate::new("eppdev-1.com", 1, "eppdev-contact-2", "epP4uthd#v", contacts, gen_client_tr_id("eppdev").unwrap().as_str());
// println!("{}", domain_create.serialize().unwrap());
client.transact::<_, EppDomainCreateResponse>(&domain_create).await.unwrap(); client.transact::<_, EppDomainCreateResponse>(&domain_create).await.unwrap();
} }
@ -145,8 +140,6 @@ async fn update_domain(client: &mut EppClient) {
domain_update.add(add); domain_update.add(add);
domain_update.remove(remove); domain_update.remove(remove);
// println!("{}", domain_update.serialize().unwrap());
client.transact::<_, EppDomainUpdateResponse>(&domain_update).await.unwrap(); client.transact::<_, EppDomainUpdateResponse>(&domain_update).await.unwrap();
} }
@ -211,16 +204,12 @@ async fn create_host(client: &mut EppClient) {
let host_create = EppHostCreate::new(host, gen_client_tr_id("eppdev").unwrap().as_str()); let host_create = EppHostCreate::new(host, gen_client_tr_id("eppdev").unwrap().as_str());
// println!("{}", host_create.serialize().unwrap());
client.transact::<_, EppHostCreateResponse>(&host_create).await.unwrap(); client.transact::<_, EppHostCreateResponse>(&host_create).await.unwrap();
} }
async fn query_host(client: &mut EppClient) { async fn query_host(client: &mut EppClient) {
let host_info = EppHostInfo::new("host2.eppdev-1.com", gen_client_tr_id("eppdev").unwrap().as_str()); let host_info = EppHostInfo::new("host2.eppdev-1.com", gen_client_tr_id("eppdev").unwrap().as_str());
// println!("{}", host_info.serialize().unwrap());
client.transact::<_, EppHostInfoResponse>(&host_info).await.unwrap(); client.transact::<_, EppHostInfoResponse>(&host_info).await.unwrap();
} }
@ -249,8 +238,6 @@ async fn update_host(client: &mut EppClient) {
// host_update.remove(remove); // host_update.remove(remove);
host_update.info(HostChangeInfo { name: "host2.eppdev-1.com".to_string_value() }); host_update.info(HostChangeInfo { name: "host2.eppdev-1.com".to_string_value() });
// println!("{}", host_update.serialize().unwrap());
client.transact::<_, EppHostUpdateResponse>(&host_update).await.unwrap(); client.transact::<_, EppHostUpdateResponse>(&host_update).await.unwrap();
} }
@ -263,8 +250,6 @@ async fn delete_host(client: &mut EppClient) {
async fn poll_message(client: &mut EppClient) { async fn poll_message(client: &mut EppClient) {
let message_poll = EppMessagePoll::new(gen_client_tr_id("eppdev").unwrap().as_str()); let message_poll = EppMessagePoll::new(gen_client_tr_id("eppdev").unwrap().as_str());
// println!("{}", message_poll.serialize().unwrap());
client.transact::<_, EppMessagePollResponse>(&message_poll).await.unwrap(); client.transact::<_, EppMessagePollResponse>(&message_poll).await.unwrap();
} }
@ -284,11 +269,10 @@ async fn hello(client: &mut EppClient) {
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
env_logger::init();
let mut client = match EppClient::new("verisign").await { let mut client = match EppClient::new("verisign").await {
Ok(client) => { Ok(client) => client,
println!("{:?}", client.greeting());
client
},
Err(e) => panic!("Error: {}", e) Err(e) => panic!("Error: {}", e)
}; };
@ -296,7 +280,7 @@ async fn main() {
// hello(&mut client).await; // hello(&mut client).await;
let response = check_domains(&mut client).await; check_domains(&mut client).await;
// check_contacts(&mut client).await; // check_contacts(&mut client).await;

View File

@ -5,6 +5,7 @@
//! ```rust //! ```rust
//! use epp_client::EppClient; //! use epp_client::EppClient;
//! use epp_client::epp::{EppDomainCheck, EppDomainCheckResponse}; //! use epp_client::epp::{EppDomainCheck, EppDomainCheckResponse};
//! use epp_client::epp::generate_client_tr_id;
//! //!
//! #[tokio::main] //! #[tokio::main]
//! async fn main() { //! async fn main() {
@ -20,7 +21,7 @@
//! println!("{:?}", greeting); //! println!("{:?}", greeting);
//! //!
//! // Execute an EPP Command against the registry with distinct request and response objects //! // Execute an EPP Command against the registry with distinct request and response objects
//! let domain_check = EppDomainCheck::new(vec!["eppdev.com", "eppdev.net"], "client-trid-12345"); //! let domain_check = EppDomainCheck::new(vec!["eppdev.com", "eppdev.net"], generate_client_tr_id(&client).as_str());
//! let response = client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap(); //! let response = client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap();
//! println!("{:?}", response); //! println!("{:?}", response);
//! } //! }
@ -28,7 +29,7 @@
use futures::executor::block_on; use futures::executor::block_on;
use std::{error::Error, fmt::Debug}; use std::{error::Error, fmt::Debug};
// use std::time::SystemTime; use std::time::SystemTime;
use std::sync::mpsc; use std::sync::mpsc;
// use std::sync::Arc; // use std::sync::Arc;
@ -39,6 +40,7 @@ use crate::epp::request::{generate_client_tr_id, EppHello, EppLogin, EppLogout};
use crate::epp::response::{EppGreeting, EppCommandResponseStatus, EppCommandResponse, EppCommandResponseError}; use crate::epp::response::{EppGreeting, EppCommandResponseStatus, EppCommandResponse, EppCommandResponseError};
use crate::epp::xml::EppXml; use crate::epp::xml::EppXml;
/// Connects to the registry and returns an logged-in instance of EppClient for further transactions
async fn connect(registry: &'static str) -> Result<EppClient, Box<dyn Error>> { async fn connect(registry: &'static str) -> Result<EppClient, Box<dyn Error>> {
let registry_creds = match CONFIG.registry(registry) { let registry_creds = match CONFIG.registry(registry) {
Some(creds) => creds, Some(creds) => creds,
@ -78,9 +80,8 @@ async fn connect(registry: &'static str) -> Result<EppClient, Box<dyn Error>> {
} }
/// Instances of the EppClient type are used to transact with the registry /// Instances of the EppClient type are used to transact with the registry
/// An instance is first created, then various EPP request and response object /// Once initialized, the EppClient instance can serialize EPP requests to XML and send them
/// types are converted to EPP XML to be sent to the registry and the responses /// to the registry and deserialize the XML responses from the registry to local types
/// from the registry are converted to local types
pub struct EppClient { pub struct EppClient {
credentials: (String, String), credentials: (String, String),
ext_uris: Option<Vec<String>>, ext_uris: Option<Vec<String>>,
@ -88,13 +89,15 @@ pub struct EppClient {
// pub client_tr_id_fn: Arc<dyn Fn(&EppClient) -> String + Send + Sync>, // pub client_tr_id_fn: Arc<dyn Fn(&EppClient) -> String + Send + Sync>,
} }
// fn default_client_tr_id_fn(client: &EppClient) -> String { /// A function to generate a simple client TRID. Should only be used for testing, library users
// let timestamp = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { /// should generate a client TRID according to their own requirements
// Ok(time) => time, pub fn default_client_tr_id_fn(client: &EppClient) -> String {
// Err(e) => panic!("Error in client TRID gen function: {}", e) let timestamp = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
// }; Ok(time) => time,
// format!("{}:{}", &client.username(), timestamp.as_secs()) Err(e) => panic!("Error in client TRID gen function: {}", e)
// } };
format!("{}:{}", &client.username(), timestamp.as_secs())
}
impl EppClient { impl EppClient {
/// Fetches the username used in the registry connection /// Fetches the username used in the registry connection
@ -113,6 +116,7 @@ impl EppClient {
connect(registry).await connect(registry).await
} }
/// Makes a login request to the registry and initializes an EppClient instance with it
async fn build(connection: EppConnection, credentials: (String, String), ext_uris: Option<Vec<String>>) -> Result<EppClient, Box<dyn Error>> { async fn build(connection: EppConnection, credentials: (String, String), ext_uris: Option<Vec<String>>) -> Result<EppClient, Box<dyn Error>> {
let mut client = EppClient { let mut client = EppClient {
connection: connection, connection: connection,
@ -144,12 +148,8 @@ impl EppClient {
pub async fn transact<T: EppXml + Debug, E: EppXml + Debug>(&mut self, request: &T) -> Result<E::Output, error::Error> { pub async fn transact<T: EppXml + Debug, E: EppXml + Debug>(&mut self, request: &T) -> Result<E::Output, error::Error> {
let epp_xml = request.serialize()?; let epp_xml = request.serialize()?;
debug!("request: {}", epp_xml);
let response = self.connection.transact(&epp_xml).await?; let response = self.connection.transact(&epp_xml).await?;
debug!("response: {}", response);
let status = EppCommandResponseStatus::deserialize(&response)?; let status = EppCommandResponseStatus::deserialize(&response)?;
if status.data.result.code < 2000 { if status.data.result.code < 2000 {
@ -167,17 +167,17 @@ impl EppClient {
self.connection.transact(&xml).await self.connection.transact(&xml).await
} }
/// Return the greeting received on establishment of the connection in raw xml form /// Returns the greeting received on establishment of the connection in raw xml form
pub fn xml_greeting(&self) -> String { pub fn xml_greeting(&self) -> String {
return String::from(&self.connection.greeting) return String::from(&self.connection.greeting)
} }
/// Return the greeting received on establishment of the connection as an `EppGreeting` instance /// Returns the greeting received on establishment of the connection as an `EppGreeting` instance
pub fn greeting(&self) -> Result<EppGreeting, error::Error> { pub fn greeting(&self) -> Result<EppGreeting, error::Error> {
EppGreeting::deserialize(&self.connection.greeting) EppGreeting::deserialize(&self.connection.greeting)
} }
/// Send the EPP Logout command to log out of the EPP session /// Sends the EPP Logout command to log out of the EPP session
pub async fn logout(&mut self) -> Result<EppCommandResponse, error::Error> { pub async fn logout(&mut self) -> Result<EppCommandResponse, error::Error> {
let client_tr_id = generate_client_tr_id(&self.credentials.0).unwrap(); let client_tr_id = generate_client_tr_id(&self.credentials.0).unwrap();
let epp_logout = EppLogout::new(client_tr_id.as_str()); let epp_logout = EppLogout::new(client_tr_id.as_str());

View File

@ -44,7 +44,7 @@ impl EppConnection {
async fn write(&mut self, buf: &Vec<u8>) -> Result<(), Box<dyn Error>> { async fn write(&mut self, buf: &Vec<u8>) -> Result<(), Box<dyn Error>> {
let wrote = self.stream.writer.write(buf).await?; let wrote = self.stream.writer.write(buf).await?;
debug!("Wrote {} bytes", wrote); debug!("{}: Wrote {} bytes", self.registry, wrote);
Ok(()) Ok(())
} }
@ -71,7 +71,7 @@ impl EppConnection {
let buf_size :usize = u32::from_be_bytes(buf).try_into()?; let buf_size :usize = u32::from_be_bytes(buf).try_into()?;
let message_size = buf_size - 4; let message_size = buf_size - 4;
debug!("Message buffer size: {}", message_size); debug!("{}: Response buffer size: {}", self.registry, message_size);
let mut buf = BytesMut::with_capacity(4096); let mut buf = BytesMut::with_capacity(4096);
let mut read_buf = vec![0u8; 4096]; let mut read_buf = vec![0u8; 4096];
@ -80,14 +80,14 @@ impl EppConnection {
loop { loop {
let read = self.stream.reader.read(&mut read_buf).await?; let read = self.stream.reader.read(&mut read_buf).await?;
debug!("Read: {} bytes", read); debug!("{}: Read: {} bytes", self.registry, read);
buf.extend_from_slice(&read_buf[0..read]); buf.extend_from_slice(&read_buf[0..read]);
read_size = read_size + read; read_size = read_size + read;
debug!("Total read: {} bytes", read_size); debug!("{}: Total read: {} bytes", self.registry, read_size);
if read == 0 { if read == 0 {
panic!("Unexpected eof") panic!("{}: Unexpected eof", self.registry)
} else if read_size >= message_size { } else if read_size >= message_size {
break; break;
} }
@ -109,13 +109,17 @@ impl EppConnection {
/// Send an EPP XML request to the registry and return the response /// Send an EPP XML request to the registry and return the response
/// receieved to the request /// receieved to the request
pub async fn transact(&mut self, content: &str) -> Result<String, Box<dyn Error>> { pub async fn transact(&mut self, content: &str) -> Result<String, Box<dyn Error>> {
debug!("{}: request: {}", self.registry, content);
self.send_epp_request(&content).await?; self.send_epp_request(&content).await?;
self.get_epp_response().await let response = self.get_epp_response().await?;
debug!("{}: request: {}", self.registry, response);
Ok(response)
} }
async fn close(&mut self) -> Result<(), Box<dyn Error>> { async fn close(&mut self) -> Result<(), Box<dyn Error>> {
debug!("Closing {} connection", self.registry); info!("{}: Closing connection", self.registry);
self.stream.writer.shutdown().await?; self.stream.writer.shutdown().await?;
Ok(()) Ok(())
@ -133,7 +137,7 @@ impl Drop for EppConnection {
pub async fn epp_connect(registry_creds: &EppClientConnection) -> Result<ConnectionStream, error::Error> { pub async fn epp_connect(registry_creds: &EppClientConnection) -> Result<ConnectionStream, error::Error> {
let (host, port) = registry_creds.connection_details(); let (host, port) = registry_creds.connection_details();
debug!("Server: {}\r\nPort: {}", host, port); info!("Connecting: EPP Server: {} Port: {}", host, port);
let addr = (host.as_str(), port) let addr = (host.as_str(), port)
.to_socket_addrs()? .to_socket_addrs()?

View File

@ -1,4 +1,3 @@
pub mod command;
pub mod object; pub mod object;
pub mod request; pub mod request;
pub mod response; pub mod response;
@ -43,3 +42,5 @@ pub use response::host::info::*;
pub use response::host::update::*; pub use response::host::update::*;
pub use response::message::ack::*; pub use response::message::ack::*;
pub use response::message::poll::*; pub use response::message::poll::*;
pub use crate::connection::client::default_client_tr_id_fn as generate_client_tr_id;

View File

@ -1,25 +0,0 @@
use crate::epp::object::{ElementName, StringValue};
use epp_client_macros::*;
use serde::ser::{SerializeStruct, Serializer};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "command")]
pub struct Command<T: ElementName> {
pub command: T,
#[serde(rename = "clTRID")]
pub client_tr_id: StringValue,
}
impl<T: ElementName + Serialize> Serialize for Command<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let command_name = self.command.element_name();
let mut state = serializer.serialize_struct("command", 2)?;
state.serialize_field(command_name, &self.command)?;
state.serialize_field("clTRID", &self.client_tr_id)?;
state.end()
}
}

View File

@ -1,3 +1,5 @@
//! Data types common to EPP Requests and Responses
pub mod data; pub mod data;
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
@ -5,6 +7,8 @@ use std::fmt::Display;
use crate::epp::xml::{EPP_XMLNS, EPP_XMLNS_XSI, EPP_XSI_SCHEMA_LOCATION}; use crate::epp::xml::{EPP_XMLNS, EPP_XMLNS_XSI, EPP_XSI_SCHEMA_LOCATION};
/// Wraps String for easier serialization to and from values that are inner text
/// for tags rather than attributes
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct StringValue(String); pub struct StringValue(String);
@ -20,6 +24,7 @@ impl Display for StringValue {
} }
} }
/// Trait for StringValue type to add easier conversion from str and String
pub trait StringValueTrait { pub trait StringValueTrait {
fn to_string_value(&self) -> StringValue; fn to_string_value(&self) -> StringValue;
} }
@ -36,20 +41,28 @@ impl StringValueTrait for String {
} }
} }
/// Trait to set correct value for xml tags when tags are being generated from generic types
pub trait ElementName { pub trait ElementName {
fn element_name(&self) -> &'static str; fn element_name(&self) -> &'static str;
} }
/// An EPP XML Document that is used either as an EPP XML request or
/// an EPP XML response
#[derive(Deserialize, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
#[serde(rename = "epp")] #[serde(rename = "epp")]
pub struct EppObject<T: ElementName> { pub struct EppObject<T: ElementName> {
/// XML namespace for the <epp> tag
pub xmlns: String, pub xmlns: String,
/// Schema namespace for the <epp> tag
#[serde(rename = "xmlns:xsi")] #[serde(rename = "xmlns:xsi")]
pub xmlns_xsi: String, pub xmlns_xsi: String,
/// Schema location attribute for <epp>
#[serde(rename = "xsi:schemaLocation")] #[serde(rename = "xsi:schemaLocation")]
pub xsi_schema_location: String, pub xsi_schema_location: String,
/// the request or response object that is set or received in the EPP XML document
#[serde(alias = "greeting", alias = "response")] #[serde(alias = "greeting", alias = "response")]
pub data: T, pub data: T,
// TODO: save serialized xml in the instance for debugging or client logging purposes
// #[serde(skip)] // #[serde(skip)]
// pub xml: Option<String>, // pub xml: Option<String>,
} }
@ -69,14 +82,18 @@ impl<T: ElementName + Serialize> Serialize for EppObject<T> {
} }
} }
/// The <option> type in EPP XML login requests
#[derive(Serialize, Deserialize, Debug, PartialEq)] #[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename = "options")] #[serde(rename = "options")]
pub struct Options { pub struct Options {
/// The EPP version being used
pub version: StringValue, pub version: StringValue,
/// The language that will be used during EPP transactions
pub lang: StringValue, pub lang: StringValue,
} }
impl Options { impl Options {
/// Creates an Options object with version and lang data
pub fn build(version: &str, lang: &str) -> Options { pub fn build(version: &str, lang: &str) -> Options {
Options { Options {
version: version.to_string_value(), version: version.to_string_value(),
@ -85,22 +102,28 @@ impl Options {
} }
} }
/// The <svcExtension> type in EPP XML
#[derive(Serialize, Deserialize, Debug, PartialEq)] #[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename = "svcExtension")] #[serde(rename = "svcExtension")]
pub struct ServiceExtension { pub struct ServiceExtension {
/// The service extension URIs being represented by <extURI> in EPP XML
#[serde(rename = "extURI")] #[serde(rename = "extURI")]
pub ext_uris: Option<Vec<StringValue>>, pub ext_uris: Option<Vec<StringValue>>,
} }
/// The <svcs> type in EPP XML
#[derive(Serialize, Deserialize, Debug, PartialEq)] #[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Services { pub struct Services {
/// The service URIs being used by this EPP session represented by <objURI> in EPP XML
#[serde(rename = "objURI")] #[serde(rename = "objURI")]
pub obj_uris: Vec<StringValue>, pub obj_uris: Vec<StringValue>,
/// The <svcExtention> being used in this EPP session
#[serde(rename = "svcExtension")] #[serde(rename = "svcExtension")]
pub svc_ext: Option<ServiceExtension>, pub svc_ext: Option<ServiceExtension>,
} }
impl<T: ElementName> EppObject<T> { impl<T: ElementName> EppObject<T> {
/// Create the enclosing EPP XML tag <epp> for data that represents an EPP XML request or response
pub fn build(data: T) -> EppObject<T> { pub fn build(data: T) -> EppObject<T> {
EppObject { EppObject {
// xml: None, // xml: None,

View File

@ -1,15 +1,21 @@
//! Common data types included in EPP Requests and Responses
use crate::epp::object::{StringValue, StringValueTrait}; use crate::epp::object::{StringValue, StringValueTrait};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// The <status> attribute on EPP XML for domain transactions
pub type DomainStatus = ContactStatus; pub type DomainStatus = ContactStatus;
/// The <status> attribute on EPP XML for host transactions
pub type HostStatus = ContactStatus; pub type HostStatus = ContactStatus;
/// The <hostObj> or <hostAttr> types under an <ns> tag on domain transactions
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub enum DomainNsList { pub enum DomainNsList {
HostAttrList(HostAttrList), HostAttrList(HostAttrList),
HostObjList(HostObjList), HostObjList(HostObjList),
} }
/// The <hostAddr> types domain or host transactions
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostAddr { pub struct HostAddr {
#[serde(rename = "ip")] #[serde(rename = "ip")]
@ -19,6 +25,7 @@ pub struct HostAddr {
} }
impl HostAddr { impl HostAddr {
/// Creates a 'v4' type HostAddr (mostly useful when you don't want to include an 'ip' attr in the XML)
pub fn new(ip_version: &str, address: &str) -> HostAddr { pub fn new(ip_version: &str, address: &str) -> HostAddr {
HostAddr { HostAddr {
ip_version: Some(ip_version.to_string()), ip_version: Some(ip_version.to_string()),
@ -26,6 +33,7 @@ impl HostAddr {
} }
} }
/// Creates a 'v4' type HostAddr
pub fn new_v4(address: &str) -> HostAddr { pub fn new_v4(address: &str) -> HostAddr {
HostAddr { HostAddr {
ip_version: Some("v4".to_string()), ip_version: Some("v4".to_string()),
@ -33,6 +41,7 @@ impl HostAddr {
} }
} }
/// Creates a 'v6' type HostAddr
pub fn new_v6(address: &str) -> HostAddr { pub fn new_v6(address: &str) -> HostAddr {
HostAddr { HostAddr {
ip_version: Some("v6".to_string()), ip_version: Some("v6".to_string()),
@ -41,49 +50,66 @@ impl HostAddr {
} }
} }
/// The <host> type for host transactions
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct Host { pub struct Host {
/// The <hostName> tag
pub name: StringValue, pub name: StringValue,
/// The <hostAddr> tags
#[serde(rename = "addr")] #[serde(rename = "addr")]
pub addresses: Option<Vec<HostAddr>>, pub addresses: Option<Vec<HostAddr>>,
} }
/// The <hostAttr> type for domain transactions
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostAttr { pub struct HostAttr {
/// The <hostName> tag
#[serde(rename = "hostName")] #[serde(rename = "hostName")]
pub name: StringValue, pub name: StringValue,
/// The <hostAddr> tags
#[serde(rename = "hostAddr")] #[serde(rename = "hostAddr")]
pub addresses: Option<Vec<HostAddr>>, pub addresses: Option<Vec<HostAddr>>,
} }
/// The list of <hostAttr> types for domain transactions. Typically under an <ns> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostAttrList { pub struct HostAttrList {
/// The list of <hostAttr> tags
#[serde(rename = "hostAttr")] #[serde(rename = "hostAttr")]
pub hosts: Vec<HostAttr>, pub hosts: Vec<HostAttr>,
} }
/// The list of <hostObj> types for domain transactions. Typically under an <ns> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostObjList { pub struct HostObjList {
/// The list of <hostObj> tags
#[serde(rename = "hostObj")] #[serde(rename = "hostObj")]
pub hosts: Vec<StringValue>, pub hosts: Vec<StringValue>,
} }
/// The <contact> type on domain creation and update requests
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainContact { pub struct DomainContact {
/// The contact id
#[serde(rename = "$value")] #[serde(rename = "$value")]
pub id: String, pub id: String,
/// The contact type attr (usually admin, billing, or tech in most registries)
#[serde(rename = "type")] #[serde(rename = "type")]
pub contact_type: String, pub contact_type: String,
} }
/// The <period> type for registration, renewal or transfer on domain transactions
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct Period { pub struct Period {
/// The interval (usually 'y' indicating years)
unit: String, unit: String,
/// The length of the registration, renewal or transfer period (usually in years)
#[serde(rename = "$value")] #[serde(rename = "$value")]
length: u16, length: u16,
} }
impl Period { impl Period {
/// Creates a new period in years
pub fn new(length: u16) -> Period { pub fn new(length: u16) -> Period {
Period { Period {
unit: "y".to_string(), unit: "y".to_string(),
@ -91,55 +117,75 @@ impl Period {
} }
} }
/// Sets the period unit ('y' for years, most commonly)
pub fn set_unit(&mut self, unit: &str) { pub fn set_unit(&mut self, unit: &str) {
self.unit = unit.to_string(); self.unit = unit.to_string();
} }
} }
/// The <status> type on contact transactions
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactStatus { pub struct ContactStatus {
/// The status name, represented by the 's' attr on <status> tags
#[serde(rename = "s")] #[serde(rename = "s")]
pub status: String, pub status: String,
} }
/// The data for <voice> and <fax> types on domain transactions
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Phone { pub struct Phone {
/// The inner text on the <voice> and <fax> tags
#[serde(rename = "$value")] #[serde(rename = "$value")]
pub number: String, pub number: String,
/// The value of the 'x' attr on <voice> and <fax> tags
#[serde(rename = "x")] #[serde(rename = "x")]
extension: Option<String>, extension: Option<String>,
} }
/// The <addr> type on contact transactions
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Address { pub struct Address {
/// The <street> tags under <addr>
street: Vec<StringValue>, street: Vec<StringValue>,
/// The <city> tag under <addr>
city: StringValue, city: StringValue,
/// The <sp> tag under <addr>
#[serde(rename = "sp")] #[serde(rename = "sp")]
province: StringValue, province: StringValue,
/// The <pc> tag under <addr>
#[serde(rename = "pc")] #[serde(rename = "pc")]
postal_code: StringValue, postal_code: StringValue,
/// The <cc> tag under <addr>
#[serde(rename = "cc")] #[serde(rename = "cc")]
country_code: StringValue, country_code: StringValue,
} }
/// The <postalInfo> type on contact transactions
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PostalInfo { pub struct PostalInfo {
/// The 'type' attr on <postalInfo>
#[serde(rename = "type")] #[serde(rename = "type")]
info_type: String, info_type: String,
/// The <name> tag under <postalInfo>
name: StringValue, name: StringValue,
/// The <org> tag under <postalInfo>
#[serde(rename = "org")] #[serde(rename = "org")]
organization: StringValue, organization: StringValue,
/// The <addr> tag under <postalInfo>
#[serde(rename = "addr")] #[serde(rename = "addr")]
address: Address, address: Address,
} }
/// The <authInfo> tag for domain and contact transactions
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AuthInfo { pub struct AuthInfo {
/// The <pw> tag under <authInfo>
#[serde(rename = "pw")] #[serde(rename = "pw")]
pub password: StringValue, pub password: StringValue,
} }
impl Phone { impl Phone {
/// Creates a new Phone instance with a given phone number
pub fn new(number: &str) -> Phone { pub fn new(number: &str) -> Phone {
Phone { Phone {
extension: None, extension: None,
@ -147,12 +193,14 @@ impl Phone {
} }
} }
/// Sets the extension value of the Phone type
pub fn set_extension(&mut self, ext: &str) { pub fn set_extension(&mut self, ext: &str) {
self.extension = Some(ext.to_string()); self.extension = Some(ext.to_string());
} }
} }
impl AuthInfo { impl AuthInfo {
/// Creates an AuthInfo instance with the given password
pub fn new(password: &str) -> AuthInfo { pub fn new(password: &str) -> AuthInfo {
AuthInfo { AuthInfo {
password: password.to_string_value(), password: password.to_string_value(),
@ -161,6 +209,7 @@ impl AuthInfo {
} }
impl Address { impl Address {
/// Creates a new Address instance
pub fn new( pub fn new(
street: Vec<&str>, street: Vec<&str>,
city: &str, city: &str,
@ -184,6 +233,7 @@ impl Address {
} }
impl PostalInfo { impl PostalInfo {
/// Creates a new PostalInfo instance
pub fn new(info_type: &str, name: &str, organization: &str, address: Address) -> PostalInfo { pub fn new(info_type: &str, name: &str, organization: &str, address: Address) -> PostalInfo {
PostalInfo { PostalInfo {
info_type: info_type.to_string(), info_type: info_type.to_string(),

View File

@ -3,11 +3,10 @@ pub mod domain;
pub mod host; pub mod host;
pub mod message; pub mod message;
use serde::{Deserialize, Serialize}; use serde::{ser::SerializeStruct, ser::Serializer, Deserialize, Serialize};
use std::error::Error; use std::error::Error;
use std::time::SystemTime; use std::time::SystemTime;
use crate::epp::command::Command;
use crate::epp::object::{ use crate::epp::object::{
ElementName, EppObject, Options, ServiceExtension, Services, StringValue, StringValueTrait, ElementName, EppObject, Options, ServiceExtension, Services, StringValue, StringValueTrait,
}; };
@ -18,6 +17,27 @@ pub type EppHello = EppObject<Hello>;
pub type EppLogin = EppObject<Command<Login>>; pub type EppLogin = EppObject<Command<Login>>;
pub type EppLogout = EppObject<Command<Logout>>; pub type EppLogout = EppObject<Command<Logout>>;
#[derive(Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "command")]
pub struct Command<T: ElementName> {
pub command: T,
#[serde(rename = "clTRID")]
pub client_tr_id: StringValue,
}
impl<T: ElementName + Serialize> Serialize for Command<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let command_name = self.command.element_name();
let mut state = serializer.serialize_struct("command", 2)?;
state.serialize_field(command_name, &self.command)?;
state.serialize_field("clTRID", &self.client_tr_id)?;
state.end()
}
}
pub fn generate_client_tr_id(username: &str) -> Result<String, Box<dyn Error>> { pub fn generate_client_tr_id(username: &str) -> Result<String, Box<dyn Error>> {
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?; let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
Ok(format!("{}:{}", username, timestamp.as_secs())) Ok(format!("{}:{}", username, timestamp.as_secs()))

View File

@ -1,27 +1,62 @@
//! Types for EPP contact check request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_CONTACT_XMLNS; use crate::epp::xml::EPP_CONTACT_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for contact <check> command
///
/// ## Usage
///
/// ```rust
/// use epp_client::EppClient;
/// use epp_client::epp::{EppContactCheck, EppContactCheckResponse};
/// use epp_client::epp::generate_client_tr_id;
///
/// #[tokio::main]
/// async fn main() {
/// // Create an instance of EppClient, specifying the name of the registry as in
/// // the config file
/// let mut client = match EppClient::new("verisign").await {
/// Ok(client) => client,
/// Err(e) => panic!("Failed to create EppClient: {}", e)
/// };
///
/// // Create an EppContactCheck instance
/// let contact_check = EppContactCheck::new(vec!["epp-client-c1", "epp-client-c2"], generate_client_tr_id(&client).as_str());
///
/// // send it to the registry and receive a response of type EppContactCheckResponse
/// let response = client.transact::<_, EppContactCheckResponse>(&contact_check).await.unwrap();
///
/// println!("{:?}", response);
/// }
/// ```
pub type EppContactCheck = EppObject<Command<ContactCheck>>; pub type EppContactCheck = EppObject<Command<ContactCheck>>;
/// Type that represents the <check> command for contact transactions
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactList { pub struct ContactList {
/// The XML namespace for the contact <check>
xmlns: String, xmlns: String,
/// The list of contact ids to check for availability
#[serde(rename = "id")] #[serde(rename = "id")]
pub contact_ids: Vec<StringValue>, pub contact_ids: Vec<StringValue>,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "check")] #[element_name(name = "check")]
/// The <command> type for contact check command
pub struct ContactCheck { pub struct ContactCheck {
/// The <check> tag for the contact check command
#[serde(rename = "check")] #[serde(rename = "check")]
list: ContactList, list: ContactList,
} }
impl EppContactCheck { impl EppContactCheck {
/// Creates an EppObject corresponding to the <epp> tag with data for a contact check request
pub fn new(contact_ids: Vec<&str>, client_tr_id: &str) -> EppContactCheck { pub fn new(contact_ids: Vec<&str>, client_tr_id: &str) -> EppContactCheck {
let contact_ids = contact_ids let contact_ids = contact_ids
.iter() .iter()

View File

@ -1,34 +1,48 @@
//! Types for EPP contact create request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data; use crate::epp::object::data;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_CONTACT_XMLNS; use crate::epp::xml::EPP_CONTACT_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for contact <create> command
pub type EppContactCreate = EppObject<Command<ContactCreate>>; pub type EppContactCreate = EppObject<Command<ContactCreate>>;
/// Type for elements under the contact <create> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct Contact { pub struct Contact {
/// XML namespace for contact commands
xmlns: String, xmlns: String,
/// Contact <id> tag
id: StringValue, id: StringValue,
/// Contact <postalInfo> tag
#[serde(rename = "postalInfo")] #[serde(rename = "postalInfo")]
postal_info: data::PostalInfo, postal_info: data::PostalInfo,
/// Contact <voice> tag
voice: data::Phone, voice: data::Phone,
/// Contact <fax> tag,
fax: Option<data::Phone>, fax: Option<data::Phone>,
/// Contact <email> tag
email: StringValue, email: StringValue,
/// Contact <authInfo> tag
#[serde(rename = "authInfo")] #[serde(rename = "authInfo")]
auth_info: data::AuthInfo, auth_info: data::AuthInfo,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "create")] #[element_name(name = "create")]
/// Type for EPP XML <create> command for contacts
pub struct ContactCreate { pub struct ContactCreate {
/// Data for <create> command for contact
#[serde(rename = "create")] #[serde(rename = "create")]
pub contact: Contact, pub contact: Contact,
} }
impl EppContactCreate { impl EppContactCreate {
/// Creates a new EppObject for contact create corresponding to the <epp> tag in EPP XML
pub fn new( pub fn new(
id: &str, id: &str,
email: &str, email: &str,
@ -55,6 +69,7 @@ impl EppContactCreate {
}) })
} }
/// Sets the <fax> data for the request
pub fn set_fax(&mut self, fax: data::Phone) { pub fn set_fax(&mut self, fax: data::Phone) {
self.data.command.contact.fax = Some(fax); self.data.command.contact.fax = Some(fax);
} }

View File

@ -1,26 +1,35 @@
//! Types for EPP contact delete request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_CONTACT_XMLNS; use crate::epp::xml::EPP_CONTACT_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type for the <epp> request for contact <delete> command
pub type EppContactDelete = EppObject<Command<ContactDelete>>; pub type EppContactDelete = EppObject<Command<ContactDelete>>;
/// Type containing the data for the <delete> tag for contacts
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactDeleteData { pub struct ContactDeleteData {
/// XML namespace for the <delete> command for contacts
xmlns: String, xmlns: String,
/// The id of the contact to be deleted
id: StringValue, id: StringValue,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "delete")] #[element_name(name = "delete")]
/// The <delete> type for the contact delete EPP command
pub struct ContactDelete { pub struct ContactDelete {
#[serde(rename = "delete")] #[serde(rename = "delete")]
/// The data for the <delete> tag for a contact delete command
contact: ContactDeleteData, contact: ContactDeleteData,
} }
impl EppContactDelete { impl EppContactDelete {
/// Creates a new EppObject for contact delete corresponding to the <epp> tag in EPP XML
pub fn new(id: &str, client_tr_id: &str) -> EppContactDelete { pub fn new(id: &str, client_tr_id: &str) -> EppContactDelete {
EppObject::build(Command::<ContactDelete> { EppObject::build(Command::<ContactDelete> {
command: ContactDelete { command: ContactDelete {

View File

@ -1,29 +1,39 @@
//! Types for EPP contact info request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::AuthInfo; use crate::epp::object::data::AuthInfo;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_CONTACT_XMLNS; use crate::epp::xml::EPP_CONTACT_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type for the <epp> request for contact <info> command
pub type EppContactInfo = EppObject<Command<ContactInfo>>; pub type EppContactInfo = EppObject<Command<ContactInfo>>;
/// Type for elements under the contact <info> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactInfoData { pub struct ContactInfoData {
/// XML namespace for contact commands
xmlns: String, xmlns: String,
/// The contact id for the info command
id: StringValue, id: StringValue,
/// The <authInfo> data
#[serde(rename = "authInfo")] #[serde(rename = "authInfo")]
auth_info: AuthInfo, auth_info: AuthInfo,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "info")] #[element_name(name = "info")]
/// Type for EPP XML <info> command for contacts
pub struct ContactInfo { pub struct ContactInfo {
/// Data for <info> command for contact
#[serde(rename = "info")] #[serde(rename = "info")]
info: ContactInfoData, info: ContactInfoData,
} }
impl EppContactInfo { impl EppContactInfo {
/// Creates a new EppObject for contact info corresponding to the <epp> tag in EPP XML
pub fn new(id: &str, auth_password: &str, client_tr_id: &str) -> EppContactInfo { pub fn new(id: &str, auth_password: &str, client_tr_id: &str) -> EppContactInfo {
EppObject::build(Command::<ContactInfo> { EppObject::build(Command::<ContactInfo> {
command: ContactInfo { command: ContactInfo {

View File

@ -1,15 +1,19 @@
//! Types for EPP contact create request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{AuthInfo, ContactStatus, Phone, PostalInfo}; use crate::epp::object::data::{AuthInfo, ContactStatus, Phone, PostalInfo};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::response::contact::info::EppContactInfoResponse; use crate::epp::response::contact::info::EppContactInfoResponse;
use crate::epp::xml::EPP_CONTACT_XMLNS; use crate::epp::xml::EPP_CONTACT_XMLNS;
use crate::error; use crate::error;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for contact <update> command
pub type EppContactUpdate = EppObject<Command<ContactUpdate>>; pub type EppContactUpdate = EppObject<Command<ContactUpdate>>;
/// Type for elements under the <chg> tag for contact update request
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactChangeInfo { pub struct ContactChangeInfo {
#[serde(rename = "postalInfo")] #[serde(rename = "postalInfo")]
@ -21,11 +25,13 @@ pub struct ContactChangeInfo {
auth_info: Option<AuthInfo>, auth_info: Option<AuthInfo>,
} }
/// Type for list of elements of the <status> tag for contact update request
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct StatusList { pub struct StatusList {
status: Vec<ContactStatus>, status: Vec<ContactStatus>,
} }
/// Type for elements under the contact <update> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactUpdateData { pub struct ContactUpdateData {
xmlns: String, xmlns: String,
@ -40,12 +46,15 @@ pub struct ContactUpdateData {
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")] #[element_name(name = "update")]
/// Type for EPP XML <update> command for contacts
pub struct ContactUpdate { pub struct ContactUpdate {
/// The data under the <update> tag for the contact update
#[serde(rename = "update")] #[serde(rename = "update")]
contact: ContactUpdateData, contact: ContactUpdateData,
} }
impl EppContactUpdate { impl EppContactUpdate {
/// Creates a new EppObject for contact update corresponding to the <epp> tag in EPP XML
pub fn new(id: &str, client_tr_id: &str) -> EppContactUpdate { pub fn new(id: &str, client_tr_id: &str) -> EppContactUpdate {
EppObject::build(Command::<ContactUpdate> { EppObject::build(Command::<ContactUpdate> {
command: ContactUpdate { command: ContactUpdate {
@ -61,6 +70,7 @@ impl EppContactUpdate {
}) })
} }
/// Sets the data for the <chg> tag for the contact update request
pub fn set_info( pub fn set_info(
&mut self, &mut self,
email: &str, email: &str,
@ -77,6 +87,7 @@ impl EppContactUpdate {
}); });
} }
/// Sets the data for the <fax> tag under <chg> for the contact update request
pub fn set_fax(&mut self, fax: Phone) { pub fn set_fax(&mut self, fax: Phone) {
match &mut self.data.command.contact.change_info { match &mut self.data.command.contact.change_info {
Some(ref mut info) => info.fax = Some(fax), Some(ref mut info) => info.fax = Some(fax),
@ -84,14 +95,17 @@ impl EppContactUpdate {
} }
} }
/// Sets the data for the <add> tag for the contact update request
pub fn add_statuses(&mut self, statuses: Vec<ContactStatus>) { pub fn add_statuses(&mut self, statuses: Vec<ContactStatus>) {
self.data.command.contact.add_statuses = Some(StatusList { status: statuses }); self.data.command.contact.add_statuses = Some(StatusList { status: statuses });
} }
/// Sets the data for the <rem> tag for the contact update request
pub fn remove_statuses(&mut self, statuses: Vec<ContactStatus>) { pub fn remove_statuses(&mut self, statuses: Vec<ContactStatus>) {
self.data.command.contact.remove_statuses = Some(StatusList { status: statuses }); self.data.command.contact.remove_statuses = Some(StatusList { status: statuses });
} }
/// Loads data into the <chg> tag from an existing EppContactInfoResponse object
pub fn load_from_epp_contact_info( pub fn load_from_epp_contact_info(
&mut self, &mut self,
contact_info: EppContactInfoResponse, contact_info: EppContactInfoResponse,

View File

@ -1,27 +1,36 @@
//! Types for EPP domain check request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for domain <check> command
pub type EppDomainCheck = EppObject<Command<DomainCheck>>; pub type EppDomainCheck = EppObject<Command<DomainCheck>>;
/// Type for <name> elements under the domain <check> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainList { pub struct DomainList {
/// XML namespace for domain commands
pub xmlns: String, pub xmlns: String,
#[serde(rename = "name")] #[serde(rename = "name")]
/// List of domains to be checked for availability
pub domains: Vec<StringValue>, pub domains: Vec<StringValue>,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "check")] #[element_name(name = "check")]
/// Type for EPP XML <check> command for domains
pub struct DomainCheck { pub struct DomainCheck {
/// The object holding the list of domains to be checked
#[serde(rename = "check")] #[serde(rename = "check")]
list: DomainList, list: DomainList,
} }
impl EppDomainCheck { impl EppDomainCheck {
/// Creates a new EppObject for domain check corresponding to the <epp> tag in EPP XML
pub fn new(domains: Vec<&str>, client_tr_id: &str) -> EppDomainCheck { pub fn new(domains: Vec<&str>, client_tr_id: &str) -> EppDomainCheck {
let domains = domains let domains = domains
.iter() .iter()

View File

@ -1,37 +1,58 @@
//! Types for EPP domain create request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{ use crate::epp::object::data::{
AuthInfo, DomainContact, HostAttr, HostAttrList, HostObjList, Period, AuthInfo, DomainContact, HostAttr, HostAttrList, HostObjList, Period,
}; };
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for domain <create> command
/// with <hostObj> elements in the request for <ns> list
pub type EppDomainCreate = EppObject<Command<DomainCreate<HostObjList>>>; pub type EppDomainCreate = EppObject<Command<DomainCreate<HostObjList>>>;
/// Type that represents the <epp> request for domain <create> command
/// with <hostAttr> elements in the request for <ns> list
pub type EppDomainCreateWithHostAttr = EppObject<Command<DomainCreate<HostAttrList>>>; pub type EppDomainCreateWithHostAttr = EppObject<Command<DomainCreate<HostAttrList>>>;
/// Type for elements under the domain <create> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainCreateData<T> { pub struct DomainCreateData<T> {
/// XML namespace for domain commands
xmlns: String, xmlns: String,
/// The domain name
name: StringValue, name: StringValue,
/// The period of registration
period: Period, period: Period,
/// The list of nameserver hosts
/// either of type `HostObjList` or `HostAttrList`
ns: Option<T>, ns: Option<T>,
/// The domain registrant
registrant: Option<StringValue>, registrant: Option<StringValue>,
/// The list of contacts for the domain
#[serde(rename = "contact")] #[serde(rename = "contact")]
contacts: Option<Vec<DomainContact>>, contacts: Option<Vec<DomainContact>>,
/// The auth info for the domain
#[serde(rename = "authInfo")] #[serde(rename = "authInfo")]
auth_info: AuthInfo, auth_info: AuthInfo,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "create")] #[element_name(name = "create")]
/// Type for EPP XML <create> command for domains
pub struct DomainCreate<T> { pub struct DomainCreate<T> {
/// The data for the domain to be created with
/// T being the type of nameserver list (`HostObjList` or `HostAttrList`)
/// to be supplied
#[serde(rename = "create")] #[serde(rename = "create")]
domain: DomainCreateData<T>, domain: DomainCreateData<T>,
} }
impl EppDomainCreate { impl EppDomainCreate {
/// Creates a new EppObject for domain create corresponding to the <epp> tag in EPP XML
/// with the <ns> tag containing <hostObj> tags
pub fn new_with_ns( pub fn new_with_ns(
name: &str, name: &str,
period: u16, period: u16,
@ -62,6 +83,8 @@ impl EppDomainCreate {
}) })
} }
/// Creates a new EppObject for domain create corresponding to the <epp> tag in EPP XML
/// without any nameservers
pub fn new( pub fn new(
name: &str, name: &str,
period: u16, period: u16,
@ -86,6 +109,8 @@ impl EppDomainCreate {
}) })
} }
/// Creates a new EppObject for domain create corresponding to the <epp> tag in EPP XML
/// without any contacts
pub fn new_without_contacts( pub fn new_without_contacts(
name: &str, name: &str,
period: u16, period: u16,
@ -108,6 +133,8 @@ impl EppDomainCreate {
}) })
} }
/// Creates a new EppObject for domain create corresponding to the <epp> tag in EPP XML
/// with the <ns> tag containing <hostAttr> tags
pub fn new_with_host_attr( pub fn new_with_host_attr(
name: &str, name: &str,
period: u16, period: u16,

View File

@ -1,26 +1,35 @@
//! Types for EPP domain delete request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for domain <delete> command
pub type EppDomainDelete = EppObject<Command<DomainDelete>>; pub type EppDomainDelete = EppObject<Command<DomainDelete>>;
/// Type for <name> element under the domain <delete> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainDeleteData { pub struct DomainDeleteData {
/// XML namespace for domain commands
xmlns: String, xmlns: String,
/// The domain to be deleted
name: StringValue, name: StringValue,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "delete")] #[element_name(name = "delete")]
/// Type for EPP XML <delete> command for domains
pub struct DomainDelete { pub struct DomainDelete {
/// The data under the <delete> tag for domain deletion
#[serde(rename = "delete")] #[serde(rename = "delete")]
domain: DomainDeleteData, domain: DomainDeleteData,
} }
impl EppDomainDelete { impl EppDomainDelete {
/// Creates a new EppObject for domain delete corresponding to the <epp> tag in EPP XML
pub fn new(name: &str, client_tr_id: &str) -> EppDomainDelete { pub fn new(name: &str, client_tr_id: &str) -> EppDomainDelete {
EppObject::build(Command::<DomainDelete> { EppObject::build(Command::<DomainDelete> {
command: DomainDelete { command: DomainDelete {

View File

@ -1,34 +1,46 @@
//! Types for EPP domain info request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for domain <info> command
pub type EppDomainInfo = EppObject<Command<DomainInfo>>; pub type EppDomainInfo = EppObject<Command<DomainInfo>>;
/// Type for data under the <name> element tag for the domain <info> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct Domain { pub struct Domain {
/// The hosts attribute. Default value is "all"
hosts: String, hosts: String,
/// The name of the domain
#[serde(rename = "$value")] #[serde(rename = "$value")]
name: String, name: String,
} }
/// Type for <name> element under the domain <info> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainInfoData { pub struct DomainInfoData {
/// XML namespace for domain commands
xmlns: String, xmlns: String,
/// The data for the domain to be queried
#[serde(rename = "name")] #[serde(rename = "name")]
domain: Domain, domain: Domain,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "info")] #[element_name(name = "info")]
/// Type for EPP XML <info> command for domains
pub struct DomainInfo { pub struct DomainInfo {
/// The data under the <info> tag for domain info
#[serde(rename = "info")] #[serde(rename = "info")]
info: DomainInfoData, info: DomainInfoData,
} }
impl EppDomainInfo { impl EppDomainInfo {
/// Creates a new EppObject for domain info corresponding to the <epp> tag in EPP XML
pub fn new(name: &str, client_tr_id: &str) -> EppDomainInfo { pub fn new(name: &str, client_tr_id: &str) -> EppDomainInfo {
EppObject::build(Command::<DomainInfo> { EppObject::build(Command::<DomainInfo> {
command: DomainInfo { command: DomainInfo {

View File

@ -1,31 +1,42 @@
//! Types for EPP domain renew request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::Period; use crate::epp::object::data::Period;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use chrono::NaiveDate; use chrono::NaiveDate;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for domain <renew> command
pub type EppDomainRenew = EppObject<Command<DomainRenew>>; pub type EppDomainRenew = EppObject<Command<DomainRenew>>;
/// Type for data under the domain <renew> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainRenewData { pub struct DomainRenewData {
/// XML namespace for domain commands
xmlns: String, xmlns: String,
/// The name of the domain to be renewed
name: StringValue, name: StringValue,
/// The current expiry date of the domain in 'Y-m-d' format
#[serde(rename = "curExpDate")] #[serde(rename = "curExpDate")]
current_expiry_date: StringValue, current_expiry_date: StringValue,
/// The period of renewal
period: Period, period: Period,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "renew")] #[element_name(name = "renew")]
/// Type for EPP XML <renew> command for domains
pub struct DomainRenew { pub struct DomainRenew {
/// The data under the <renew> tag for the domain renewal
#[serde(rename = "renew")] #[serde(rename = "renew")]
domain: DomainRenewData, domain: DomainRenewData,
} }
impl EppDomainRenew { impl EppDomainRenew {
/// Creates a new EppObject for domain renew corresponding to the <epp> tag in EPP XML
pub fn new( pub fn new(
name: &str, name: &str,
current_expiry_date: NaiveDate, current_expiry_date: NaiveDate,

View File

@ -1,36 +1,55 @@
//! Types for EPP domain transfer request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{AuthInfo, Period}; use crate::epp::object::data::{AuthInfo, Period};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for transfer request for domain
pub type EppDomainTransferRequest = EppObject<Command<DomainTransfer>>; pub type EppDomainTransferRequest = EppObject<Command<DomainTransfer>>;
/// Type that represents the <epp> request for transfer approval for domains
pub type EppDomainTransferApprove = EppObject<Command<DomainTransfer>>; pub type EppDomainTransferApprove = EppObject<Command<DomainTransfer>>;
/// Type that represents the <epp> request for transfer rejection for domains
pub type EppDomainTransferReject = EppObject<Command<DomainTransfer>>; pub type EppDomainTransferReject = EppObject<Command<DomainTransfer>>;
/// Type that represents the <epp> request for transfer request cancellation for domains
pub type EppDomainTransferCancel = EppObject<Command<DomainTransfer>>; pub type EppDomainTransferCancel = EppObject<Command<DomainTransfer>>;
/// Type that represents the <epp> request for transfer request query for domains
pub type EppDomainTransferQuery = EppObject<Command<DomainTransfer>>; pub type EppDomainTransferQuery = EppObject<Command<DomainTransfer>>;
/// Type for elements under the domain <transfer> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainTransferData { pub struct DomainTransferData {
/// XML namespace for domain commands
xmlns: String, xmlns: String,
/// The name of the domain under transfer
name: StringValue, name: StringValue,
/// The period of renewal upon a successful transfer
/// Only applicable in case of a transfer request
period: Option<Period>, period: Option<Period>,
/// The authInfo for the domain under transfer
/// Only applicable to domain transfer and domain transfer query requests
#[serde(rename = "authInfo")] #[serde(rename = "authInfo")]
auth_info: Option<AuthInfo>, auth_info: Option<AuthInfo>,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "transfer")] #[element_name(name = "transfer")]
/// Type for EPP XML <transfer> command for domains
pub struct DomainTransfer { pub struct DomainTransfer {
/// The transfer operation to perform indicated by the 'op' attr
/// The values are one of transfer, approve, reject, cancel, or query
#[serde(rename = "op")] #[serde(rename = "op")]
operation: String, operation: String,
/// The data under the <transfer> tag in the transfer request
#[serde(rename = "transfer")] #[serde(rename = "transfer")]
domain: DomainTransferData, domain: DomainTransferData,
} }
impl EppDomainTransferRequest { impl EppDomainTransferRequest {
/// Creates a new EppObject for domain transfer request corresponding to the <epp> tag in EPP XML
pub fn request( pub fn request(
name: &str, name: &str,
years: u16, years: u16,
@ -51,12 +70,14 @@ impl EppDomainTransferRequest {
}) })
} }
/// Sets the period for renewal in case of a successful transfer
pub fn set_period(&mut self, period: Period) { pub fn set_period(&mut self, period: Period) {
self.data.command.domain.period = Some(period); self.data.command.domain.period = Some(period);
} }
} }
impl EppDomainTransferApprove { impl EppDomainTransferApprove {
/// Creates a new EppObject for domain transfer approval corresponding to the <epp> tag in EPP XML
pub fn approve(name: &str, client_tr_id: &str) -> EppDomainTransferApprove { pub fn approve(name: &str, client_tr_id: &str) -> EppDomainTransferApprove {
EppObject::build(Command::<DomainTransfer> { EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer { command: DomainTransfer {
@ -74,6 +95,7 @@ impl EppDomainTransferApprove {
} }
impl EppDomainTransferCancel { impl EppDomainTransferCancel {
/// Creates a new EppObject for domain transfer request cancellation corresponding to the <epp> tag in EPP XML
pub fn cancel(name: &str, client_tr_id: &str) -> EppDomainTransferCancel { pub fn cancel(name: &str, client_tr_id: &str) -> EppDomainTransferCancel {
EppObject::build(Command::<DomainTransfer> { EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer { command: DomainTransfer {
@ -91,6 +113,7 @@ impl EppDomainTransferCancel {
} }
impl EppDomainTransferReject { impl EppDomainTransferReject {
/// Creates a new EppObject for domain transfer rejection corresponding to the <epp> tag in EPP XML
pub fn reject(name: &str, client_tr_id: &str) -> EppDomainTransferReject { pub fn reject(name: &str, client_tr_id: &str) -> EppDomainTransferReject {
EppObject::build(Command::<DomainTransfer> { EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer { command: DomainTransfer {
@ -108,6 +131,7 @@ impl EppDomainTransferReject {
} }
impl EppDomainTransferQuery { impl EppDomainTransferQuery {
/// Creates a new EppObject for domain transfer request query corresponding to the <epp> tag in EPP XML
pub fn query(name: &str, auth_password: &str, client_tr_id: &str) -> EppDomainTransferQuery { pub fn query(name: &str, auth_password: &str, client_tr_id: &str) -> EppDomainTransferQuery {
EppObject::build(Command::<DomainTransfer> { EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer { command: DomainTransfer {

View File

@ -1,50 +1,75 @@
//! Types for EPP domain check request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{AuthInfo, DomainContact, DomainStatus, HostAttrList, HostObjList}; use crate::epp::object::data::{AuthInfo, DomainContact, DomainStatus, HostAttrList, HostObjList};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for domain <update> command
/// with <hostObj> elements in the request for <ns> list
pub type EppDomainUpdate = EppObject<Command<DomainUpdate<HostObjList>>>; pub type EppDomainUpdate = EppObject<Command<DomainUpdate<HostObjList>>>;
/// Type that represents the <epp> request for domain <update> command
/// with <hostAttr> elements in the request for <ns> list
pub type EppDomainUpdateWithHostAttr = EppObject<Command<DomainUpdate<HostAttrList>>>; pub type EppDomainUpdateWithHostAttr = EppObject<Command<DomainUpdate<HostAttrList>>>;
/// Type for elements under the <chg> tag for domain update
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainChangeInfo { pub struct DomainChangeInfo {
/// The new registrant contact for the domain
pub registrant: Option<StringValue>, pub registrant: Option<StringValue>,
/// The new auth info for the domain
#[serde(rename = "authInfo")] #[serde(rename = "authInfo")]
pub auth_info: Option<AuthInfo>, pub auth_info: Option<AuthInfo>,
} }
/// Type for elements under the <add> and <rem> tags for domain update
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainAddRemove<T> { pub struct DomainAddRemove<T> {
/// The list of nameservers to add or remove
/// Type T can be either a `HostObjList` or `HostAttrList`
#[serde(rename = "ns")] #[serde(rename = "ns")]
pub ns: Option<T>, pub ns: Option<T>,
/// The list of contacts to add to or remove from the domain
#[serde(rename = "contact")] #[serde(rename = "contact")]
pub contacts: Option<Vec<DomainContact>>, pub contacts: Option<Vec<DomainContact>>,
/// The list of statuses to add to or remove from the domain
#[serde(rename = "status")] #[serde(rename = "status")]
pub statuses: Option<Vec<DomainStatus>>, pub statuses: Option<Vec<DomainStatus>>,
} }
/// Type for elements under the <update> tag for domain update
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainUpdateData<T> { pub struct DomainUpdateData<T> {
/// XML namespace for domain commands
xmlns: String, xmlns: String,
/// The name of the domain to update
name: StringValue, name: StringValue,
/// `DomainAddRemove` Object containing the list of elements to be added
/// to the domain
add: Option<DomainAddRemove<T>>, add: Option<DomainAddRemove<T>>,
/// `DomainAddRemove` Object containing the list of elements to be removed
/// from the domain
#[serde(rename = "rem")] #[serde(rename = "rem")]
remove: Option<DomainAddRemove<T>>, remove: Option<DomainAddRemove<T>>,
/// The data under the <chg> tag for domain update
#[serde(rename = "chg")] #[serde(rename = "chg")]
change_info: Option<DomainChangeInfo>, change_info: Option<DomainChangeInfo>,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")] #[element_name(name = "update")]
/// Type for EPP XML <update> command for domains
pub struct DomainUpdate<T> { pub struct DomainUpdate<T> {
#[serde(rename = "update")] #[serde(rename = "update")]
domain: DomainUpdateData<T>, domain: DomainUpdateData<T>,
} }
impl EppDomainUpdate { impl EppDomainUpdate {
/// Creates a new EppObject for domain update corresponding to the <epp> tag in EPP XML
/// with the <ns> tag containing <hostObj> tags
pub fn new(name: &str, client_tr_id: &str) -> EppDomainUpdate { pub fn new(name: &str, client_tr_id: &str) -> EppDomainUpdate {
EppObject::build(Command::<DomainUpdate<HostObjList>> { EppObject::build(Command::<DomainUpdate<HostObjList>> {
command: DomainUpdate { command: DomainUpdate {
@ -60,20 +85,25 @@ impl EppDomainUpdate {
}) })
} }
/// Sets the data for the <chg> tag
pub fn info(&mut self, info: DomainChangeInfo) { pub fn info(&mut self, info: DomainChangeInfo) {
self.data.command.domain.change_info = Some(info); self.data.command.domain.change_info = Some(info);
} }
/// Sets the data for the <add> tag
pub fn add(&mut self, add: DomainAddRemove<HostObjList>) { pub fn add(&mut self, add: DomainAddRemove<HostObjList>) {
self.data.command.domain.add = Some(add); self.data.command.domain.add = Some(add);
} }
/// Sets the data for the <rem> tag
pub fn remove(&mut self, remove: DomainAddRemove<HostObjList>) { pub fn remove(&mut self, remove: DomainAddRemove<HostObjList>) {
self.data.command.domain.remove = Some(remove); self.data.command.domain.remove = Some(remove);
} }
} }
impl EppDomainUpdateWithHostAttr { impl EppDomainUpdateWithHostAttr {
/// Creates a new EppObject for domain update corresponding to the <epp> tag in EPP XML
/// with the <ns> tag containing <hostAttr> tags
pub fn new(name: &str, client_tr_id: &str) -> EppDomainUpdateWithHostAttr { pub fn new(name: &str, client_tr_id: &str) -> EppDomainUpdateWithHostAttr {
EppObject::build(Command::<DomainUpdate<HostAttrList>> { EppObject::build(Command::<DomainUpdate<HostAttrList>> {
command: DomainUpdate { command: DomainUpdate {
@ -89,14 +119,17 @@ impl EppDomainUpdateWithHostAttr {
}) })
} }
/// Sets the data for the <chg> tag
pub fn info(&mut self, info: DomainChangeInfo) { pub fn info(&mut self, info: DomainChangeInfo) {
self.data.command.domain.change_info = Some(info); self.data.command.domain.change_info = Some(info);
} }
/// Sets the data for the <add> tag
pub fn add(&mut self, add: DomainAddRemove<HostAttrList>) { pub fn add(&mut self, add: DomainAddRemove<HostAttrList>) {
self.data.command.domain.add = Some(add); self.data.command.domain.add = Some(add);
} }
/// Sets the data for the <rem> tag
pub fn remove(&mut self, remove: DomainAddRemove<HostAttrList>) { pub fn remove(&mut self, remove: DomainAddRemove<HostAttrList>) {
self.data.command.domain.remove = Some(remove); self.data.command.domain.remove = Some(remove);
} }

View File

@ -1,27 +1,36 @@
//! Types for EPP host check request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_HOST_XMLNS; use crate::epp::xml::EPP_HOST_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for host <check> command
pub type EppHostCheck = EppObject<Command<HostCheck>>; pub type EppHostCheck = EppObject<Command<HostCheck>>;
/// Type for data under the host <check> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostList { pub struct HostList {
/// XML namespace for host commands
xmlns: String, xmlns: String,
/// List of hosts to be checked for availability
#[serde(rename = "name")] #[serde(rename = "name")]
pub hosts: Vec<StringValue>, pub hosts: Vec<StringValue>,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "check")] #[element_name(name = "check")]
/// Type for EPP XML <check> command for hosts
pub struct HostCheck { pub struct HostCheck {
/// The instance holding the list of hosts to be checked
#[serde(rename = "check")] #[serde(rename = "check")]
list: HostList, list: HostList,
} }
impl EppHostCheck { impl EppHostCheck {
/// Creates a new EppObject for host check corresponding to the <epp> tag in EPP XML
pub fn new(hosts: Vec<&str>, client_tr_id: &str) -> EppHostCheck { pub fn new(hosts: Vec<&str>, client_tr_id: &str) -> EppHostCheck {
let hosts = hosts let hosts = hosts
.iter() .iter()

View File

@ -1,29 +1,39 @@
//! Types for EPP host create request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{Host, HostAddr}; use crate::epp::object::data::{Host, HostAddr};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_HOST_XMLNS; use crate::epp::xml::EPP_HOST_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for host <create> command
pub type EppHostCreate = EppObject<Command<HostCreate>>; pub type EppHostCreate = EppObject<Command<HostCreate>>;
/// Type for data under the host <create> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostCreateData { pub struct HostCreateData {
/// XML namespace for host commands
xmlns: String, xmlns: String,
/// The name of the host to be created
pub name: StringValue, pub name: StringValue,
/// The list of IP addresses for the host
#[serde(rename = "addr")] #[serde(rename = "addr")]
pub addresses: Option<Vec<HostAddr>>, pub addresses: Option<Vec<HostAddr>>,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "create")] #[element_name(name = "create")]
/// Type for EPP XML <create> command for hosts
pub struct HostCreate { pub struct HostCreate {
/// The instance holding the data for the host to be created
#[serde(rename = "create")] #[serde(rename = "create")]
host: HostCreateData, host: HostCreateData,
} }
impl EppHostCreate { impl EppHostCreate {
/// Creates a new EppObject for host create corresponding to the <epp> tag in EPP XML
pub fn new(host: Host, client_tr_id: &str) -> EppHostCreate { pub fn new(host: Host, client_tr_id: &str) -> EppHostCreate {
let host_create = HostCreate { let host_create = HostCreate {
host: HostCreateData { host: HostCreateData {

View File

@ -1,26 +1,35 @@
//! Types for EPP host delete request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_HOST_XMLNS; use crate::epp::xml::EPP_HOST_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for host <delete> command
pub type EppHostDelete = EppObject<Command<HostDelete>>; pub type EppHostDelete = EppObject<Command<HostDelete>>;
/// Type for data under the host <delete> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostDeleteData { pub struct HostDeleteData {
/// XML namespace for host commands
xmlns: String, xmlns: String,
/// The host to be deleted
name: StringValue, name: StringValue,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "delete")] #[element_name(name = "delete")]
/// Type for EPP XML <delete> command for hosts
pub struct HostDelete { pub struct HostDelete {
/// The instance holding the data for the host to be deleted
#[serde(rename = "delete")] #[serde(rename = "delete")]
host: HostDeleteData, host: HostDeleteData,
} }
impl EppHostDelete { impl EppHostDelete {
/// Creates a new EppObject for host delete corresponding to the <epp> tag in EPP XML
pub fn new(name: &str, client_tr_id: &str) -> EppHostDelete { pub fn new(name: &str, client_tr_id: &str) -> EppHostDelete {
EppObject::build(Command::<HostDelete> { EppObject::build(Command::<HostDelete> {
command: HostDelete { command: HostDelete {

View File

@ -1,26 +1,35 @@
//! Types for EPP host info request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_HOST_XMLNS; use crate::epp::xml::EPP_HOST_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for host <info> command
pub type EppHostInfo = EppObject<Command<HostInfo>>; pub type EppHostInfo = EppObject<Command<HostInfo>>;
/// Type for data under the host <info> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostInfoData { pub struct HostInfoData {
/// XML namespace for host commands
xmlns: String, xmlns: String,
/// The name of the host to be queried
name: StringValue, name: StringValue,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "info")] #[element_name(name = "info")]
/// Type for EPP XML <info> command for hosts
pub struct HostInfo { pub struct HostInfo {
/// The instance holding the data for the host query
#[serde(rename = "info")] #[serde(rename = "info")]
info: HostInfoData, info: HostInfoData,
} }
impl EppHostInfo { impl EppHostInfo {
/// Creates a new EppObject for host info corresponding to the <epp> tag in EPP XML
pub fn new(name: &str, client_tr_id: &str) -> EppHostInfo { pub fn new(name: &str, client_tr_id: &str) -> EppHostInfo {
EppObject::build(Command::<HostInfo> { EppObject::build(Command::<HostInfo> {
command: HostInfo { command: HostInfo {

View File

@ -1,45 +1,62 @@
//! Types for EPP host update request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{HostAddr, HostStatus}; use crate::epp::object::data::{HostAddr, HostStatus};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_HOST_XMLNS; use crate::epp::xml::EPP_HOST_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for host <update> command
pub type EppHostUpdate = EppObject<Command<HostUpdate>>; pub type EppHostUpdate = EppObject<Command<HostUpdate>>;
/// Type for data under the <chg> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostChangeInfo { pub struct HostChangeInfo {
/// The new name for the host
pub name: StringValue, pub name: StringValue,
} }
/// Type for data under the <add> and <rem> tags
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostAddRemove { pub struct HostAddRemove {
/// The IP addresses to be added to or removed from the host
#[serde(rename = "addr")] #[serde(rename = "addr")]
pub addresses: Option<Vec<HostAddr>>, pub addresses: Option<Vec<HostAddr>>,
/// The statuses to be added to or removed from the host
#[serde(rename = "status")] #[serde(rename = "status")]
pub statuses: Option<Vec<HostStatus>>, pub statuses: Option<Vec<HostStatus>>,
} }
/// Type for data under the host <update> tag
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostUpdateData { pub struct HostUpdateData {
/// XML namespace for host commands
xmlns: String, xmlns: String,
/// The name of the host
name: StringValue, name: StringValue,
/// The IP addresses and statuses to be added to the host
add: Option<HostAddRemove>, add: Option<HostAddRemove>,
/// The IP addresses and statuses to be removed from the host
#[serde(rename = "rem")] #[serde(rename = "rem")]
remove: Option<HostAddRemove>, remove: Option<HostAddRemove>,
/// The host details that need to be updated
#[serde(rename = "chg")] #[serde(rename = "chg")]
change_info: Option<HostChangeInfo>, change_info: Option<HostChangeInfo>,
} }
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")] #[element_name(name = "update")]
/// Type for EPP XML <update> command for hosts
pub struct HostUpdate { pub struct HostUpdate {
/// The instance holding the data for the host to be updated
#[serde(rename = "update")] #[serde(rename = "update")]
host: HostUpdateData, host: HostUpdateData,
} }
impl EppHostUpdate { impl EppHostUpdate {
/// Creates a new EppObject for host update corresponding to the <epp> tag in EPP XML
pub fn new(name: &str, client_tr_id: &str) -> EppHostUpdate { pub fn new(name: &str, client_tr_id: &str) -> EppHostUpdate {
EppObject::build(Command::<HostUpdate> { EppObject::build(Command::<HostUpdate> {
command: HostUpdate { command: HostUpdate {
@ -55,14 +72,17 @@ impl EppHostUpdate {
}) })
} }
/// Sets the data for the <chg> element of the host update
pub fn info(&mut self, info: HostChangeInfo) { pub fn info(&mut self, info: HostChangeInfo) {
self.data.command.host.change_info = Some(info); self.data.command.host.change_info = Some(info);
} }
/// Sets the data for the <add> element of the host update
pub fn add(&mut self, add: HostAddRemove) { pub fn add(&mut self, add: HostAddRemove) {
self.data.command.host.add = Some(add); self.data.command.host.add = Some(add);
} }
/// Sets the data for the <rem> element of the host update
pub fn remove(&mut self, remove: HostAddRemove) { pub fn remove(&mut self, remove: HostAddRemove) {
self.data.command.host.remove = Some(remove); self.data.command.host.remove = Some(remove);
} }

View File

@ -1,20 +1,28 @@
//! Types for EPP message ack request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValueTrait};
use crate::epp::request::Command;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for registry <poll op="ack"> command
pub type EppMessageAck = EppObject<Command<MessageAck>>; pub type EppMessageAck = EppObject<Command<MessageAck>>;
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "poll")] #[element_name(name = "poll")]
/// Type for EPP XML <poll> command for message ack
pub struct MessageAck { pub struct MessageAck {
/// The type of operation to perform
/// The value is "ack" for message acknowledgement
op: String, op: String,
/// The ID of the message to be acknowledged
#[serde(rename = "msgID")] #[serde(rename = "msgID")]
message_id: String, message_id: String,
} }
impl EppMessageAck { impl EppMessageAck {
/// Creates a new EppObject for <poll> ack corresponding to the <epp> tag in EPP XML
pub fn new(message_id: u32, client_tr_id: &str) -> EppMessageAck { pub fn new(message_id: u32, client_tr_id: &str) -> EppMessageAck {
EppObject::build(Command::<MessageAck> { EppObject::build(Command::<MessageAck> {
command: MessageAck { command: MessageAck {

View File

@ -1,18 +1,25 @@
//! Types for EPP message poll request
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValueTrait};
use crate::epp::request::Command;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for registry <poll op="req"> command
pub type EppMessagePoll = EppObject<Command<MessagePoll>>; pub type EppMessagePoll = EppObject<Command<MessagePoll>>;
#[derive(Serialize, Deserialize, Debug, ElementName)] #[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "poll")] #[element_name(name = "poll")]
/// Type for EPP XML <poll> command for message poll
pub struct MessagePoll { pub struct MessagePoll {
/// The type of operation to perform
/// The value is "req" for message polling
op: String, op: String,
} }
impl EppMessagePoll { impl EppMessagePoll {
/// Creates a new EppObject for <poll> req corresponding to the <epp> tag in EPP XML
pub fn new(client_tr_id: &str) -> EppMessagePoll { pub fn new(client_tr_id: &str) -> EppMessagePoll {
EppObject::build(Command::<MessagePoll> { EppObject::build(Command::<MessagePoll> {
command: MessagePoll { command: MessagePoll {

View File

@ -59,6 +59,7 @@
//! ```rust //! ```rust
//! use epp_client::EppClient; //! use epp_client::EppClient;
//! use epp_client::epp::{EppDomainCheck, EppDomainCheckResponse}; //! use epp_client::epp::{EppDomainCheck, EppDomainCheckResponse};
//! use epp_client::epp::generate_client_tr_id;
//! //!
//! #[tokio::main] //! #[tokio::main]
//! async fn main() { //! async fn main() {
@ -71,7 +72,7 @@
//! //!
//! // Make a domain check call, which returns an object of type EppDomainCheckResponse //! // Make a domain check call, which returns an object of type EppDomainCheckResponse
//! // that contains the result of the call //! // that contains the result of the call
//! let domain_check = EppDomainCheck::new(vec!["eppdev.com", "eppdev.net"], "client-trid-12345"); //! let domain_check = EppDomainCheck::new(vec!["eppdev.com", "eppdev.net"], generate_client_tr_id(&client).as_str());
//! //!
//! let response = client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap(); //! let response = client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap();
//! //!
@ -84,6 +85,7 @@
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate epp_client_macros;
pub mod config; pub mod config;
pub mod connection; pub mod connection;