added macro for serializer element name for generic objects
This commit is contained in:
parent
7851602ef5
commit
fd72c80023
|
@ -1,3 +1,4 @@
|
||||||
/target
|
/target
|
||||||
/misc
|
**/target
|
||||||
|
/epp-client/misc
|
||||||
Cargo.lock
|
Cargo.lock
|
29
Cargo.toml
29
Cargo.toml
|
@ -1,25 +1,6 @@
|
||||||
[package]
|
[workspace]
|
||||||
name = "epp-client"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
members = [
|
||||||
|
'epp-client-macros',
|
||||||
[[example]]
|
'epp-client'
|
||||||
name = "example-client"
|
]
|
||||||
path = "examples/client.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
bytes = "1"
|
|
||||||
confy = "0.4"
|
|
||||||
futures = "0.3"
|
|
||||||
lazy_static = "1.4"
|
|
||||||
quick-xml = { version = "0.22", features = [ "serialize" ] }
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
tokio = { version = "1.0", features = [ "full" ] }
|
|
||||||
tokio-rustls = "0.22"
|
|
||||||
webpki = "0.22"
|
|
||||||
webpki-roots = "0.21"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tokio-test = "*"
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "epp-client-macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = { version = "1", features = ["full", "fold"] }
|
||||||
|
quote = "1"
|
|
@ -0,0 +1,86 @@
|
||||||
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
|
||||||
|
fn element_name_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||||
|
let name = &ast.ident;
|
||||||
|
let mut elem_name = ast.ident.to_string();
|
||||||
|
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
|
||||||
|
|
||||||
|
if ast.attrs.len() > 0 {
|
||||||
|
let attribute = &ast.attrs[0];
|
||||||
|
let meta = match attribute.parse_meta() {
|
||||||
|
Ok(syn::Meta::List(meta)) => {
|
||||||
|
if meta.nested.len() > 0 {
|
||||||
|
elem_name = match &meta.nested[0] {
|
||||||
|
syn::NestedMeta::Meta(syn::Meta::NameValue(v)) => match &v.lit {
|
||||||
|
syn::Lit::Str(lit) => lit.value(),
|
||||||
|
_ => panic!("Invalid element_name attribute"),
|
||||||
|
},
|
||||||
|
_ => panic!("Invalid element_name attribute"),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
panic!("Invalid element_name attribute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => panic!("Invalid element_name attribute"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let implement = quote! {
|
||||||
|
impl #impl_generics ElementName for #name #type_generics {
|
||||||
|
fn element_name(&self) -> &'static str {
|
||||||
|
#elem_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
implement.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(ElementName, attributes(element_name))]
|
||||||
|
pub fn element_name_derive(input: TokenStream) -> TokenStream {
|
||||||
|
let ast = syn::parse(input).expect("Error while parsing ElementName macro input");
|
||||||
|
|
||||||
|
element_name_macro(&ast)
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[proc_macro_attribute]
|
||||||
|
// pub fn epp_client_command_response(_metadat: TokenStream, input: TokenStream) -> TokenStream {
|
||||||
|
// let mut ast = parse_macro_input!(input as DeriveInput);
|
||||||
|
|
||||||
|
// match &mut ast.data {
|
||||||
|
// syn::Data::Struct(ref mut data) => {
|
||||||
|
// match &mut data.fields {
|
||||||
|
// syn::Fields::Named(fields) => {
|
||||||
|
// fields.named.push(
|
||||||
|
// syn::Field::parse_named
|
||||||
|
// .parse2(quote! {
|
||||||
|
// pub result: EppResult
|
||||||
|
// })
|
||||||
|
// .unwrap()
|
||||||
|
// );
|
||||||
|
// fields.named.push(
|
||||||
|
// syn::Field::parse_named
|
||||||
|
// .parse2(quote! {
|
||||||
|
// pub tr_ids: ResponseTRID
|
||||||
|
// })
|
||||||
|
// .unwrap()
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// _ => (),
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return quote! { #ast }.into();
|
||||||
|
// }
|
||||||
|
// _ => panic!("Failed to parse CommandResponse macro input"),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[cfg(test)]
|
||||||
|
// mod tests {
|
||||||
|
// #[test]
|
||||||
|
// fn it_works() {
|
||||||
|
// assert_eq!(2 + 2, 4);
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -0,0 +1,26 @@
|
||||||
|
[package]
|
||||||
|
name = "epp-client"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "example-client"
|
||||||
|
path = "examples/client.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
epp-client-macros = { path = "../epp-client-macros" }
|
||||||
|
bytes = "1"
|
||||||
|
confy = "0.4"
|
||||||
|
futures = "0.3"
|
||||||
|
lazy_static = "1.4"
|
||||||
|
quick-xml = { version = "0.22", features = [ "serialize" ] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
tokio = { version = "1.0", features = [ "full" ] }
|
||||||
|
tokio-rustls = "0.22"
|
||||||
|
webpki = "0.22"
|
||||||
|
webpki-roots = "0.21"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tokio-test = "*"
|
|
@ -0,0 +1,57 @@
|
||||||
|
use epp_client::{epp::request::generate_client_tr_id, connection::EppClient, connection, epp::xml::EppXml, epp::response::EppGreeting};
|
||||||
|
use epp_client::epp::request::domain::check::EppDomainCheck;
|
||||||
|
use epp_client::epp::response::domain::check::EppDomainCheckResponse;
|
||||||
|
use epp_client::epp::request::contact::check::EppContactCheck;
|
||||||
|
use epp_client::epp::response::contact::check::EppContactCheckResponse;
|
||||||
|
use epp_client::epp::object::data::{PostalInfo, Address, Phone};
|
||||||
|
use epp_client::epp::request::contact::create::EppContactCreate;
|
||||||
|
|
||||||
|
async fn check_domains(client: &mut EppClient) {
|
||||||
|
let domains = vec!["eppdev.com", "hexonet.net"];
|
||||||
|
let domain_check = EppDomainCheck::new(domains, generate_client_tr_id("eppdev").unwrap().as_str());
|
||||||
|
|
||||||
|
client.transact::<EppDomainCheck, EppDomainCheckResponse>(&domain_check).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn check_contacts(client: &mut EppClient) {
|
||||||
|
let contacts = vec!["eppdev-contact-1", "eppdev-contact-2"];
|
||||||
|
let contact_check = EppContactCheck::new(contacts, generate_client_tr_id("eppdev").unwrap().as_str());
|
||||||
|
|
||||||
|
client.transact::<_, EppContactCheckResponse>(&contact_check).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn create_contact() {
|
||||||
|
let street = vec!["58", "Orchid Road"];
|
||||||
|
let address = Address::new(street, "Paris", "Paris", "392374", "FR");
|
||||||
|
let postal_info = PostalInfo::new("int", "John Doe", "Acme Widgets", address);
|
||||||
|
let mut voice = Phone::new("+47.47237942");
|
||||||
|
voice.set_extension("123");
|
||||||
|
let mut fax = Phone::new("+47.86698799");
|
||||||
|
fax.set_extension("677");
|
||||||
|
|
||||||
|
let mut contact_create = EppContactCreate::new("eppdev-contact-1", "contact@eppdev.net", postal_info, voice, "eppdev-387323", generate_client_tr_id("eppdev").unwrap().as_str());
|
||||||
|
contact_create.set_fax(fax);
|
||||||
|
|
||||||
|
println!("xml: {}", contact_create.serialize().unwrap());
|
||||||
|
|
||||||
|
//client.transact::<EppContactCheck, EppContactCheckResponse>(&contact_check).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
let mut client = match connection::connect("hexonet").await {
|
||||||
|
Ok(client) => {
|
||||||
|
let greeting = client.greeting();
|
||||||
|
let greeting_object = EppGreeting::deserialize(&greeting).unwrap();
|
||||||
|
println!("{:?}", greeting_object);
|
||||||
|
client
|
||||||
|
},
|
||||||
|
Err(e) => panic!("Error: {}", e)
|
||||||
|
};
|
||||||
|
|
||||||
|
// check_domains(&mut client).await;
|
||||||
|
|
||||||
|
check_contacts(&mut client).await;
|
||||||
|
|
||||||
|
// create_contact().await;
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ use tokio::{net::TcpStream, io::AsyncWriteExt, io::AsyncReadExt, io::split, io::
|
||||||
|
|
||||||
use crate::config::{CONFIG, EppClientConnection};
|
use crate::config::{CONFIG, EppClientConnection};
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::epp::request::{generate_client_tr_id, Login, EppLogin, Logout, EppLogout};
|
use crate::epp::request::{generate_client_tr_id, EppLogin, EppLogout};
|
||||||
use crate::epp::response::EppCommandResponse;
|
use crate::epp::response::EppCommandResponse;
|
||||||
use crate::epp::xml::EppXml;
|
use crate::epp::xml::EppXml;
|
||||||
|
|
||||||
|
@ -160,6 +160,8 @@ impl EppClient {
|
||||||
|
|
||||||
println!("Response:\r\n{}", response);
|
println!("Response:\r\n{}", response);
|
||||||
|
|
||||||
|
// let result_object = EppCommandResponse::deserialize(&response);
|
||||||
|
|
||||||
let response_obj = E::deserialize(&response)?;
|
let response_obj = E::deserialize(&response)?;
|
||||||
|
|
||||||
println!("Response:\r\n{:?}", response_obj);
|
println!("Response:\r\n{:?}", response_obj);
|
|
@ -4,4 +4,3 @@ pub mod quick_xml;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
pub mod xml;
|
pub mod xml;
|
||||||
pub use request::domain;
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub mod data;
|
||||||
|
|
||||||
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
|
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
|
||||||
|
|
||||||
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};
|
|
@ -0,0 +1,94 @@
|
||||||
|
use crate::epp::object::{StringValue, StringValueTrait};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Phone {
|
||||||
|
#[serde(rename = "$value")]
|
||||||
|
pub number: String,
|
||||||
|
#[serde(rename = "x")]
|
||||||
|
extension: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Address {
|
||||||
|
street: Vec<StringValue>,
|
||||||
|
city: StringValue,
|
||||||
|
#[serde(rename = "sp")]
|
||||||
|
province: StringValue,
|
||||||
|
#[serde(rename = "pc")]
|
||||||
|
postal_code: StringValue,
|
||||||
|
#[serde(rename = "cc")]
|
||||||
|
country_code: StringValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct PostalInfo {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
info_type: String,
|
||||||
|
name: StringValue,
|
||||||
|
#[serde(rename = "org")]
|
||||||
|
organization: StringValue,
|
||||||
|
#[serde(rename = "addr")]
|
||||||
|
address: Address,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct AuthInfo {
|
||||||
|
#[serde(rename = "pw")]
|
||||||
|
password: StringValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Phone {
|
||||||
|
pub fn new(number: &str) -> Phone {
|
||||||
|
Phone {
|
||||||
|
extension: None,
|
||||||
|
number: number.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_extension(&mut self, ext: &str) {
|
||||||
|
self.extension = Some(ext.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthInfo {
|
||||||
|
pub fn new(password: &str) -> AuthInfo {
|
||||||
|
AuthInfo {
|
||||||
|
password: password.to_string_value(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Address {
|
||||||
|
pub fn new(
|
||||||
|
street: Vec<&str>,
|
||||||
|
city: &str,
|
||||||
|
province: &str,
|
||||||
|
postal_code: &str,
|
||||||
|
country_code: &str,
|
||||||
|
) -> Address {
|
||||||
|
let street = street
|
||||||
|
.iter()
|
||||||
|
.filter_map(|s| Some(s.to_string_value()))
|
||||||
|
.collect::<Vec<StringValue>>();
|
||||||
|
|
||||||
|
Address {
|
||||||
|
street: street,
|
||||||
|
city: city.to_string_value(),
|
||||||
|
province: province.to_string_value(),
|
||||||
|
postal_code: postal_code.to_string_value(),
|
||||||
|
country_code: country_code.to_string_value(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PostalInfo {
|
||||||
|
pub fn new(info_type: &str, name: &str, organization: &str, address: Address) -> PostalInfo {
|
||||||
|
PostalInfo {
|
||||||
|
info_type: info_type.to_string(),
|
||||||
|
name: name.to_string_value(),
|
||||||
|
organization: organization.to_string_value(),
|
||||||
|
address: address,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,11 +5,12 @@ use serde::{Deserialize, Serialize};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
pub use crate::epp::command::Command;
|
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,
|
||||||
};
|
};
|
||||||
use crate::epp::xml::{EPP_LANG, EPP_VERSION};
|
use crate::epp::xml::{EPP_LANG, EPP_VERSION};
|
||||||
|
use epp_client_macros::*;
|
||||||
|
|
||||||
pub type EppHello = EppObject<Hello>;
|
pub type EppHello = EppObject<Hello>;
|
||||||
pub type EppLogin = EppObject<Command<Login>>;
|
pub type EppLogin = EppObject<Command<Login>>;
|
||||||
|
@ -20,24 +21,20 @@ pub fn generate_client_tr_id(username: &str) -> Result<String, Box<dyn Error>> {
|
||||||
Ok(format!("{}:{}", username, timestamp.as_secs()))
|
Ok(format!("{}:{}", username, timestamp.as_secs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
||||||
#[serde(rename = "hello")]
|
#[serde(rename = "hello")]
|
||||||
|
#[element_name(name = "hello")]
|
||||||
pub struct Hello;
|
pub struct Hello;
|
||||||
|
|
||||||
impl ElementName for Hello {
|
|
||||||
fn element_name(&self) -> &'static str {
|
|
||||||
"hello"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EppHello {
|
impl EppHello {
|
||||||
pub fn new() -> EppHello {
|
pub fn new() -> EppHello {
|
||||||
EppObject::build(Hello {})
|
EppObject::build(Hello {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
||||||
#[serde(rename = "login")]
|
#[serde(rename = "login")]
|
||||||
|
#[element_name(name = "login")]
|
||||||
pub struct Login {
|
pub struct Login {
|
||||||
#[serde(rename(serialize = "clID", deserialize = "clID"))]
|
#[serde(rename(serialize = "clID", deserialize = "clID"))]
|
||||||
username: StringValue,
|
username: StringValue,
|
||||||
|
@ -48,12 +45,6 @@ pub struct Login {
|
||||||
services: Services,
|
services: Services,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementName for Login {
|
|
||||||
fn element_name(&self) -> &'static str {
|
|
||||||
"login"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EppLogin {
|
impl EppLogin {
|
||||||
pub fn new(username: &str, password: &str, client_tr_id: &str) -> EppLogin {
|
pub fn new(username: &str, password: &str, client_tr_id: &str) -> EppLogin {
|
||||||
let login = Login {
|
let login = Login {
|
||||||
|
@ -92,8 +83,8 @@ impl EppLogin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[element_name(name = "logout")]
|
||||||
pub struct Logout;
|
pub struct Logout;
|
||||||
|
|
||||||
impl EppLogout {
|
impl EppLogout {
|
||||||
|
@ -104,9 +95,3 @@ impl EppLogout {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementName for Logout {
|
|
||||||
fn element_name(&self) -> &'static str {
|
|
||||||
"logout"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod check;
|
||||||
|
pub mod create;
|
|
@ -1,9 +1,10 @@
|
||||||
|
use epp_client_macros::*;
|
||||||
|
|
||||||
use crate::epp::command::Command;
|
use crate::epp::command::Command;
|
||||||
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
|
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
|
||||||
|
use crate::epp::xml::EPP_CONTACT_XMLNS;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
const EPP_CONTACT_XMLNS: &str = "urn:ietf:params:xml:ns:contact-1.0";
|
|
||||||
|
|
||||||
pub type EppContactCheck = EppObject<Command<ContactCheck>>;
|
pub type EppContactCheck = EppObject<Command<ContactCheck>>;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
@ -13,18 +14,13 @@ pub struct ContactList {
|
||||||
pub contact_ids: Vec<StringValue>,
|
pub contact_ids: Vec<StringValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, ElementName)]
|
||||||
|
#[element_name(name = "check")]
|
||||||
pub struct ContactCheck {
|
pub struct ContactCheck {
|
||||||
#[serde(rename = "check")]
|
#[serde(rename = "check")]
|
||||||
list: ContactList,
|
list: ContactList,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementName for ContactCheck {
|
|
||||||
fn element_name(&self) -> &'static str {
|
|
||||||
"check"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EppContactCheck {
|
impl EppContactCheck {
|
||||||
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
|
|
@ -0,0 +1,61 @@
|
||||||
|
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::xml::EPP_CONTACT_XMLNS;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub type EppContactCreate = EppObject<Command<ContactCreate>>;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Contact {
|
||||||
|
xmlns: String,
|
||||||
|
id: StringValue,
|
||||||
|
#[serde(rename = "postalInfo")]
|
||||||
|
postal_info: data::PostalInfo,
|
||||||
|
voice: data::Phone,
|
||||||
|
fax: Option<data::Phone>,
|
||||||
|
email: StringValue,
|
||||||
|
#[serde(rename = "authInfo")]
|
||||||
|
auth_info: data::AuthInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, ElementName)]
|
||||||
|
#[element_name(name = "create")]
|
||||||
|
pub struct ContactCreate {
|
||||||
|
#[serde(rename = "create")]
|
||||||
|
pub contact: Contact,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EppContactCreate {
|
||||||
|
pub fn new(
|
||||||
|
id: &str,
|
||||||
|
email: &str,
|
||||||
|
postal_info: data::PostalInfo,
|
||||||
|
voice: data::Phone,
|
||||||
|
auth_password: &str,
|
||||||
|
client_tr_id: &str,
|
||||||
|
) -> EppContactCreate {
|
||||||
|
let contact_create = ContactCreate {
|
||||||
|
contact: Contact {
|
||||||
|
xmlns: EPP_CONTACT_XMLNS.to_string(),
|
||||||
|
id: id.to_string_value(),
|
||||||
|
postal_info: postal_info,
|
||||||
|
voice: voice,
|
||||||
|
fax: None,
|
||||||
|
email: email.to_string_value(),
|
||||||
|
auth_info: data::AuthInfo::new(auth_password),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
EppObject::build(Command::<ContactCreate> {
|
||||||
|
command: contact_create,
|
||||||
|
client_tr_id: client_tr_id.to_string_value(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_fax(&mut self, fax: data::Phone) {
|
||||||
|
self.data.command.contact.fax = Some(fax);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod check;
|
|
@ -1,9 +1,10 @@
|
||||||
|
use epp_client_macros::*;
|
||||||
|
|
||||||
use crate::epp::command::Command;
|
use crate::epp::command::Command;
|
||||||
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
|
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
|
||||||
|
use crate::epp::xml::EPP_DOMAIN_XMLNS;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
const EPP_DOMAIN_XMLNS: &str = "urn:ietf:params:xml:ns:domain-1.0";
|
|
||||||
|
|
||||||
pub type EppDomainCheck = EppObject<Command<DomainCheck>>;
|
pub type EppDomainCheck = EppObject<Command<DomainCheck>>;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
@ -13,18 +14,13 @@ pub struct DomainList {
|
||||||
pub domains: Vec<StringValue>,
|
pub domains: Vec<StringValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, ElementName)]
|
||||||
|
#[element_name(name = "check")]
|
||||||
pub struct DomainCheck {
|
pub struct DomainCheck {
|
||||||
#[serde(rename = "check")]
|
#[serde(rename = "check")]
|
||||||
list: DomainList,
|
list: DomainList,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementName for DomainCheck {
|
|
||||||
fn element_name(&self) -> &'static str {
|
|
||||||
"check"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EppDomainCheck {
|
impl EppDomainCheck {
|
||||||
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
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod contact;
|
pub mod contact;
|
||||||
pub mod domain;
|
pub mod domain;
|
||||||
|
|
||||||
|
use epp_client_macros::*;
|
||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
use crate::epp::object::{
|
use crate::epp::object::{
|
||||||
|
@ -101,8 +102,9 @@ pub struct Dcp {
|
||||||
statement: Statement,
|
statement: Statement,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
|
#[element_name(name = "greeting")]
|
||||||
pub struct Greeting {
|
pub struct Greeting {
|
||||||
#[serde(rename = "svID")]
|
#[serde(rename = "svID")]
|
||||||
service_id: String,
|
service_id: String,
|
||||||
|
@ -128,8 +130,9 @@ pub struct ResponseTRID {
|
||||||
pub server_tr_id: StringValue,
|
pub server_tr_id: StringValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
|
#[element_name(name = "response")]
|
||||||
pub struct CommandResponse<T> {
|
pub struct CommandResponse<T> {
|
||||||
pub result: EppResult,
|
pub result: EppResult,
|
||||||
#[serde(rename = "resData")]
|
#[serde(rename = "resData")]
|
||||||
|
@ -137,15 +140,3 @@ pub struct CommandResponse<T> {
|
||||||
#[serde(rename = "trID")]
|
#[serde(rename = "trID")]
|
||||||
pub tr_ids: ResponseTRID,
|
pub tr_ids: ResponseTRID,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementName for Greeting {
|
|
||||||
fn element_name(&self) -> &'static str {
|
|
||||||
"greeting"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ElementName for CommandResponse<T> {
|
|
||||||
fn element_name(&self) -> &'static str {
|
|
||||||
"command"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod check;
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod check;
|
|
@ -7,6 +7,9 @@ pub const EPP_XMLNS: &str = "urn:ietf:params:xml:ns:epp-1.0";
|
||||||
pub const EPP_XMLNS_XSI: &str = "http://www.w3.org/2001/XMLSchema-instance";
|
pub const EPP_XMLNS_XSI: &str = "http://www.w3.org/2001/XMLSchema-instance";
|
||||||
pub const EPP_XSI_SCHEMA_LOCATION: &str = "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd";
|
pub const EPP_XSI_SCHEMA_LOCATION: &str = "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd";
|
||||||
|
|
||||||
|
pub const EPP_DOMAIN_XMLNS: &str = "urn:ietf:params:xml:ns:domain-1.0";
|
||||||
|
pub const EPP_CONTACT_XMLNS: &str = "urn:ietf:params:xml:ns:contact-1.0";
|
||||||
|
|
||||||
pub const EPP_VERSION: &str = "1.0";
|
pub const EPP_VERSION: &str = "1.0";
|
||||||
pub const EPP_LANG: &str = "en";
|
pub const EPP_LANG: &str = "en";
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
use epp_client::{epp::request::generate_client_tr_id, connection::EppClient, connection, epp::xml::EppXml, epp::response::EppGreeting};
|
|
||||||
use epp_client::epp::request::domain::EppDomainCheck;
|
|
||||||
use epp_client::epp::response::domain::EppDomainCheckResponse;
|
|
||||||
use epp_client::epp::request::contact::EppContactCheck;
|
|
||||||
use epp_client::epp::response::contact::EppContactCheckResponse;
|
|
||||||
|
|
||||||
async fn check_domains(client: &mut EppClient) {
|
|
||||||
let domains = vec!["eppdev.com", "hexonet.net"];
|
|
||||||
let domain_check = EppDomainCheck::new(domains, generate_client_tr_id("eppdev").unwrap().as_str());
|
|
||||||
|
|
||||||
client.transact::<EppDomainCheck, EppDomainCheckResponse>(&domain_check).await.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn check_contacts(client: &mut EppClient) {
|
|
||||||
let contacts = vec!["eppdev-contact-1", "eppdev-contact-2"];
|
|
||||||
let contact_check = EppContactCheck::new(contacts, generate_client_tr_id("eppdev").unwrap().as_str());
|
|
||||||
|
|
||||||
client.transact::<EppContactCheck, EppContactCheckResponse>(&contact_check).await.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
let mut client = match connection::connect("hexonet").await {
|
|
||||||
Ok(client) => {
|
|
||||||
let greeting = client.greeting();
|
|
||||||
let greeting_object = EppGreeting::deserialize(&greeting).unwrap();
|
|
||||||
println!("{:?}", greeting_object);
|
|
||||||
client
|
|
||||||
},
|
|
||||||
Err(e) => panic!("Error: {}", e)
|
|
||||||
};
|
|
||||||
|
|
||||||
check_domains(&mut client).await;
|
|
||||||
|
|
||||||
check_contacts(&mut client).await;
|
|
||||||
}
|
|
Loading…
Reference in New Issue