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"
confy = "0.4"
futures = "0.3"
env_logger = "0.9"
log = "0.4"
lazy_static = "1.4"
quick-xml = { version = "0.22", features = [ "serialize" ] }

View File

@ -1,5 +1,6 @@
use std::{error::Error, time::SystemTime};
use chrono::NaiveDate;
use env_logger;
use epp_client::EppClient;
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());
contact_create.set_fax(fax);
// println!("xml: {}", contact_create.serialize().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() }];
contact_update.remove_statuses(add_statuses);
// println!("{}", contact_update.serialize().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());
// println!("{}", domain_create.serialize().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.remove(remove);
// println!("{}", domain_update.serialize().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());
// println!("{}", host_create.serialize().unwrap());
client.transact::<_, EppHostCreateResponse>(&host_create).await.unwrap();
}
async fn query_host(client: &mut EppClient) {
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();
}
@ -249,8 +238,6 @@ async fn update_host(client: &mut EppClient) {
// host_update.remove(remove);
host_update.info(HostChangeInfo { name: "host2.eppdev-1.com".to_string_value() });
// println!("{}", host_update.serialize().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) {
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();
}
@ -284,11 +269,10 @@ async fn hello(client: &mut EppClient) {
#[tokio::main]
async fn main() {
env_logger::init();
let mut client = match EppClient::new("verisign").await {
Ok(client) => {
println!("{:?}", client.greeting());
client
},
Ok(client) => client,
Err(e) => panic!("Error: {}", e)
};
@ -296,7 +280,7 @@ async fn main() {
// hello(&mut client).await;
let response = check_domains(&mut client).await;
check_domains(&mut client).await;
// check_contacts(&mut client).await;

View File

@ -5,6 +5,7 @@
//! ```rust
//! use epp_client::EppClient;
//! use epp_client::epp::{EppDomainCheck, EppDomainCheckResponse};
//! use epp_client::epp::generate_client_tr_id;
//!
//! #[tokio::main]
//! async fn main() {
@ -20,7 +21,7 @@
//! println!("{:?}", greeting);
//!
//! // 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();
//! println!("{:?}", response);
//! }
@ -28,7 +29,7 @@
use futures::executor::block_on;
use std::{error::Error, fmt::Debug};
// use std::time::SystemTime;
use std::time::SystemTime;
use std::sync::mpsc;
// 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::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>> {
let registry_creds = match CONFIG.registry(registry) {
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
/// An instance is first created, then various EPP request and response object
/// types are converted to EPP XML to be sent to the registry and the responses
/// from the registry are converted to local types
/// Once initialized, the EppClient instance can serialize EPP requests to XML and send them
/// to the registry and deserialize the XML responses from the registry to local types
pub struct EppClient {
credentials: (String, 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>,
}
// fn default_client_tr_id_fn(client: &EppClient) -> String {
// let timestamp = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
// Ok(time) => time,
// Err(e) => panic!("Error in client TRID gen function: {}", e)
// };
// format!("{}:{}", &client.username(), timestamp.as_secs())
// }
/// A function to generate a simple client TRID. Should only be used for testing, library users
/// should generate a client TRID according to their own requirements
pub fn default_client_tr_id_fn(client: &EppClient) -> String {
let timestamp = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(time) => time,
Err(e) => panic!("Error in client TRID gen function: {}", e)
};
format!("{}:{}", &client.username(), timestamp.as_secs())
}
impl EppClient {
/// Fetches the username used in the registry connection
@ -113,6 +116,7 @@ impl EppClient {
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>> {
let mut client = EppClient {
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> {
let epp_xml = request.serialize()?;
debug!("request: {}", epp_xml);
let response = self.connection.transact(&epp_xml).await?;
debug!("response: {}", response);
let status = EppCommandResponseStatus::deserialize(&response)?;
if status.data.result.code < 2000 {
@ -167,17 +167,17 @@ impl EppClient {
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 {
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> {
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> {
let client_tr_id = generate_client_tr_id(&self.credentials.0).unwrap();
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>> {
let wrote = self.stream.writer.write(buf).await?;
debug!("Wrote {} bytes", wrote);
debug!("{}: Wrote {} bytes", self.registry, wrote);
Ok(())
}
@ -71,7 +71,7 @@ impl EppConnection {
let buf_size :usize = u32::from_be_bytes(buf).try_into()?;
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 read_buf = vec![0u8; 4096];
@ -80,14 +80,14 @@ impl EppConnection {
loop {
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]);
read_size = read_size + read;
debug!("Total read: {} bytes", read_size);
debug!("{}: Total read: {} bytes", self.registry, read_size);
if read == 0 {
panic!("Unexpected eof")
panic!("{}: Unexpected eof", self.registry)
} else if read_size >= message_size {
break;
}
@ -109,13 +109,17 @@ impl EppConnection {
/// Send an EPP XML request to the registry and return the response
/// receieved to the request
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.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>> {
debug!("Closing {} connection", self.registry);
info!("{}: Closing connection", self.registry);
self.stream.writer.shutdown().await?;
Ok(())
@ -133,7 +137,7 @@ impl Drop for EppConnection {
pub async fn epp_connect(registry_creds: &EppClientConnection) -> Result<ConnectionStream, error::Error> {
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)
.to_socket_addrs()?

View File

@ -1,4 +1,3 @@
pub mod command;
pub mod object;
pub mod request;
pub mod response;
@ -43,3 +42,5 @@ pub use response::host::info::*;
pub use response::host::update::*;
pub use response::message::ack::*;
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;
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};
/// Wraps String for easier serialization to and from values that are inner text
/// for tags rather than attributes
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
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 {
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 {
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)]
#[serde(rename = "epp")]
pub struct EppObject<T: ElementName> {
/// XML namespace for the <epp> tag
pub xmlns: String,
/// Schema namespace for the <epp> tag
#[serde(rename = "xmlns:xsi")]
pub xmlns_xsi: String,
/// Schema location attribute for <epp>
#[serde(rename = "xsi:schemaLocation")]
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")]
pub data: T,
// TODO: save serialized xml in the instance for debugging or client logging purposes
// #[serde(skip)]
// 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)]
#[serde(rename = "options")]
pub struct Options {
/// The EPP version being used
pub version: StringValue,
/// The language that will be used during EPP transactions
pub lang: StringValue,
}
impl Options {
/// Creates an Options object with version and lang data
pub fn build(version: &str, lang: &str) -> Options {
Options {
version: version.to_string_value(),
@ -85,22 +102,28 @@ impl Options {
}
}
/// The <svcExtension> type in EPP XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename = "svcExtension")]
pub struct ServiceExtension {
/// The service extension URIs being represented by <extURI> in EPP XML
#[serde(rename = "extURI")]
pub ext_uris: Option<Vec<StringValue>>,
}
/// The <svcs> type in EPP XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Services {
/// The service URIs being used by this EPP session represented by <objURI> in EPP XML
#[serde(rename = "objURI")]
pub obj_uris: Vec<StringValue>,
/// The <svcExtention> being used in this EPP session
#[serde(rename = "svcExtension")]
pub svc_ext: Option<ServiceExtension>,
}
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> {
EppObject {
// xml: None,

View File

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

View File

@ -3,11 +3,10 @@ pub mod domain;
pub mod host;
pub mod message;
use serde::{Deserialize, Serialize};
use serde::{ser::SerializeStruct, ser::Serializer, Deserialize, Serialize};
use std::error::Error;
use std::time::SystemTime;
use crate::epp::command::Command;
use crate::epp::object::{
ElementName, EppObject, Options, ServiceExtension, Services, StringValue, StringValueTrait,
};
@ -18,6 +17,27 @@ pub type EppHello = EppObject<Hello>;
pub type EppLogin = EppObject<Command<Login>>;
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>> {
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
Ok(format!("{}:{}", username, timestamp.as_secs()))

View File

@ -1,27 +1,62 @@
//! Types for EPP contact check request
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_CONTACT_XMLNS;
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>>;
/// Type that represents the <check> command for contact transactions
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactList {
/// The XML namespace for the contact <check>
xmlns: String,
/// The list of contact ids to check for availability
#[serde(rename = "id")]
pub contact_ids: Vec<StringValue>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "check")]
/// The <command> type for contact check command
pub struct ContactCheck {
/// The <check> tag for the contact check command
#[serde(rename = "check")]
list: ContactList,
}
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 {
let contact_ids = contact_ids
.iter()

View File

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

View File

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

View File

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

View File

@ -1,15 +1,19 @@
//! Types for EPP contact create request
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{AuthInfo, ContactStatus, Phone, PostalInfo};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::response::contact::info::EppContactInfoResponse;
use crate::epp::xml::EPP_CONTACT_XMLNS;
use crate::error;
use serde::{Deserialize, Serialize};
/// Type that represents the <epp> request for contact <update> command
pub type EppContactUpdate = EppObject<Command<ContactUpdate>>;
/// Type for elements under the <chg> tag for contact update request
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactChangeInfo {
#[serde(rename = "postalInfo")]
@ -21,11 +25,13 @@ pub struct ContactChangeInfo {
auth_info: Option<AuthInfo>,
}
/// Type for list of elements of the <status> tag for contact update request
#[derive(Serialize, Deserialize, Debug)]
pub struct StatusList {
status: Vec<ContactStatus>,
}
/// Type for elements under the contact <update> tag
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactUpdateData {
xmlns: String,
@ -40,12 +46,15 @@ pub struct ContactUpdateData {
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")]
/// Type for EPP XML <update> command for contacts
pub struct ContactUpdate {
/// The data under the <update> tag for the contact update
#[serde(rename = "update")]
contact: ContactUpdateData,
}
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 {
EppObject::build(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(
&mut self,
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) {
match &mut self.data.command.contact.change_info {
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>) {
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>) {
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(
&mut self,
contact_info: EppContactInfoResponse,

View File

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

View File

@ -1,37 +1,58 @@
//! Types for EPP domain create request
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{
AuthInfo, DomainContact, HostAttr, HostAttrList, HostObjList, Period,
};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::request::Command;
use crate::epp::xml::EPP_DOMAIN_XMLNS;
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>>>;
/// 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>>>;
/// Type for elements under the domain <create> tag
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCreateData<T> {
/// XML namespace for domain commands
xmlns: String,
/// The domain name
name: StringValue,
/// The period of registration
period: Period,
/// The list of nameserver hosts
/// either of type `HostObjList` or `HostAttrList`
ns: Option<T>,
/// The domain registrant
registrant: Option<StringValue>,
/// The list of contacts for the domain
#[serde(rename = "contact")]
contacts: Option<Vec<DomainContact>>,
/// The auth info for the domain
#[serde(rename = "authInfo")]
auth_info: AuthInfo,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "create")]
/// Type for EPP XML <create> command for domains
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")]
domain: DomainCreateData<T>,
}
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(
name: &str,
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(
name: &str,
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(
name: &str,
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(
name: &str,
period: u16,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -59,6 +59,7 @@
//! ```rust
//! use epp_client::EppClient;
//! use epp_client::epp::{EppDomainCheck, EppDomainCheckResponse};
//! use epp_client::epp::generate_client_tr_id;
//!
//! #[tokio::main]
//! async fn main() {
@ -71,7 +72,7 @@
//!
//! // Make a domain check call, which returns an object of type EppDomainCheckResponse
//! // 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();
//!
@ -84,6 +85,7 @@
#[macro_use]
extern crate log;
extern crate epp_client_macros;
pub mod config;
pub mod connection;