Flatten XML abstraction
This commit is contained in:
parent
3f91647370
commit
ca19e545fd
|
@ -21,7 +21,7 @@ use crate::error::Error;
|
|||
use crate::hello::{Greeting, GreetingDocument, HelloDocument};
|
||||
use crate::request::{Command, CommandDocument, Extension, Transaction};
|
||||
use crate::response::{Response, ResponseDocument, ResponseStatus};
|
||||
use crate::xml::EppXml;
|
||||
use crate::xml;
|
||||
|
||||
/// An `EppClient` provides an interface to sending EPP requests to a registry
|
||||
///
|
||||
|
@ -107,13 +107,13 @@ impl<C: Connector> EppClient<C> {
|
|||
|
||||
/// Executes an EPP Hello call and returns the response as a `Greeting`
|
||||
pub async fn hello(&mut self) -> Result<Greeting, Error> {
|
||||
let hello_xml = HelloDocument::default().serialize()?;
|
||||
let xml = xml::serialize(&HelloDocument::default())?;
|
||||
|
||||
debug!("{}: hello: {}", self.connection.registry, &hello_xml);
|
||||
let response = self.connection.transact(&hello_xml)?.await?;
|
||||
debug!("{}: hello: {}", self.connection.registry, &xml);
|
||||
let response = self.connection.transact(&xml)?.await?;
|
||||
debug!("{}: greeting: {}", self.connection.registry, &response);
|
||||
|
||||
Ok(GreetingDocument::deserialize(&response)?.data)
|
||||
Ok(xml::deserialize::<GreetingDocument>(&response)?.data)
|
||||
}
|
||||
|
||||
pub async fn transact<'c, 'e, Cmd, Ext>(
|
||||
|
@ -127,14 +127,13 @@ impl<C: Connector> EppClient<C> {
|
|||
{
|
||||
let data = data.into();
|
||||
let document = CommandDocument::new(data.command, data.extension, id);
|
||||
let xml = document.serialize()?;
|
||||
let xml = xml::serialize(&document)?;
|
||||
|
||||
debug!("{}: request: {}", self.connection.registry, &xml);
|
||||
let response = self.connection.transact(&xml)?.await?;
|
||||
debug!("{}: response: {}", self.connection.registry, &response);
|
||||
|
||||
let rsp =
|
||||
<ResponseDocument<Cmd::Response, Ext::Response> as EppXml>::deserialize(&response)?;
|
||||
let rsp = xml::deserialize::<ResponseDocument<Cmd::Response, Ext::Response>>(&response)?;
|
||||
if rsp.data.result.code.is_success() {
|
||||
return Ok(rsp.data);
|
||||
}
|
||||
|
@ -161,7 +160,7 @@ impl<C: Connector> EppClient<C> {
|
|||
|
||||
/// Returns the greeting received on establishment of the connection as an `Greeting`
|
||||
pub fn greeting(&self) -> Result<Greeting, Error> {
|
||||
GreetingDocument::deserialize(&self.connection.greeting).map(|obj| obj.data)
|
||||
xml::deserialize::<GreetingDocument>(&self.connection.greeting).map(|obj| obj.data)
|
||||
}
|
||||
|
||||
pub async fn reconnect(&mut self) -> Result<(), Error> {
|
||||
|
|
11
src/hello.rs
11
src/hello.rs
|
@ -4,7 +4,6 @@ use chrono::{DateTime, Utc};
|
|||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
|
||||
use crate::common::{Options, ServiceExtension, Services, StringValue, EPP_XMLNS};
|
||||
use crate::xml::EppXml;
|
||||
|
||||
// Request
|
||||
|
||||
|
@ -27,8 +26,6 @@ impl Default for HelloDocument {
|
|||
}
|
||||
}
|
||||
|
||||
impl EppXml for HelloDocument {}
|
||||
|
||||
// Response
|
||||
|
||||
/// Type for data within the <svcMenu> section of an EPP greeting
|
||||
|
@ -302,20 +299,18 @@ pub struct GreetingDocument {
|
|||
pub data: Greeting,
|
||||
}
|
||||
|
||||
impl EppXml for GreetingDocument {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use chrono::{TimeZone, Utc};
|
||||
|
||||
use super::{ExpiryType, GreetingDocument, HelloDocument, Relative};
|
||||
use crate::tests::get_xml;
|
||||
use crate::xml::EppXml;
|
||||
use crate::xml;
|
||||
|
||||
#[test]
|
||||
fn hello() {
|
||||
let xml = get_xml("request/hello.xml").unwrap();
|
||||
let serialized = HelloDocument::default().serialize().unwrap();
|
||||
let serialized = xml::serialize(&HelloDocument::default()).unwrap();
|
||||
|
||||
assert_eq!(xml, serialized);
|
||||
}
|
||||
|
@ -323,7 +318,7 @@ mod tests {
|
|||
#[test]
|
||||
fn greeting() {
|
||||
let xml = get_xml("response/greeting.xml").unwrap();
|
||||
let object = GreetingDocument::deserialize(xml.as_str()).unwrap();
|
||||
let object = xml::deserialize::<GreetingDocument>(xml.as_str()).unwrap();
|
||||
|
||||
assert_eq!(object.data.service_id, "ISPAPI EPP Server");
|
||||
assert_eq!(
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
use serde::{de::DeserializeOwned, ser::SerializeStruct, ser::Serializer, Serialize};
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::{
|
||||
common::{StringValue, EPP_XMLNS},
|
||||
xml::EppXml,
|
||||
};
|
||||
use crate::common::{StringValue, EPP_XMLNS};
|
||||
|
||||
pub const EPP_VERSION: &str = "1.0";
|
||||
pub const EPP_LANG: &str = "en";
|
||||
|
@ -73,5 +70,3 @@ impl<'a, Cmd, Ext> CommandDocument<'a, Cmd, Ext> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: Serialize, E: Serialize> EppXml for CommandDocument<'a, D, E> {}
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
use std::fmt::{self, Debug};
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{de::DeserializeOwned, Deserialize};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::common::StringValue;
|
||||
use crate::xml::EppXml;
|
||||
|
||||
/// Type corresponding to the <undef> tag an EPP response XML
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
|
@ -218,8 +217,6 @@ pub struct ResponseDocument<D, E> {
|
|||
pub data: Response<D, E>,
|
||||
}
|
||||
|
||||
impl<D: DeserializeOwned, E: DeserializeOwned> EppXml for ResponseDocument<D, E> {}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq)]
|
||||
#[serde(rename = "epp")]
|
||||
pub struct ResultDocument {
|
||||
|
@ -227,8 +224,6 @@ pub struct ResultDocument {
|
|||
pub data: ResponseStatus,
|
||||
}
|
||||
|
||||
impl EppXml for ResultDocument {}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
/// Type corresponding to the <response> tag in an EPP response XML
|
||||
/// without <msgQ> or <resData> sections. Generally used for error handling
|
||||
|
@ -261,12 +256,12 @@ impl<T, E> Response<T, E> {
|
|||
mod tests {
|
||||
use super::{ResultCode, ResultDocument};
|
||||
use crate::tests::{get_xml, CLTRID, SVTRID};
|
||||
use crate::xml::EppXml;
|
||||
use crate::xml;
|
||||
|
||||
#[test]
|
||||
fn error() {
|
||||
let xml = get_xml("response/error.xml").unwrap();
|
||||
let object = ResultDocument::deserialize(xml.as_str()).unwrap();
|
||||
let object = xml::deserialize::<ResultDocument>(xml.as_str()).unwrap();
|
||||
|
||||
assert_eq!(object.data.result.code, ResultCode::ObjectDoesNotExist);
|
||||
assert_eq!(object.data.result.message, "Object does not exist".into());
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
common::NoExtension,
|
||||
request::{Command, CommandDocument, Extension, Transaction},
|
||||
response::{Response, ResponseDocument},
|
||||
xml::EppXml,
|
||||
xml,
|
||||
};
|
||||
|
||||
pub(crate) const RESOURCES_DIR: &str = "./tests/resources";
|
||||
|
@ -47,8 +47,7 @@ pub(crate) fn assert_serialized<'c, 'e, Cmd, Ext>(
|
|||
let expected = get_xml(path).unwrap();
|
||||
let req = req.into();
|
||||
let document = CommandDocument::new(req.command, req.extension, CLTRID);
|
||||
let actual = EppXml::serialize(&document).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
assert_eq!(expected, xml::serialize(&document).unwrap());
|
||||
}
|
||||
|
||||
pub(crate) fn response_from_file<'c, Cmd>(
|
||||
|
@ -68,8 +67,7 @@ where
|
|||
Ext: Extension,
|
||||
{
|
||||
let xml = get_xml(path).unwrap();
|
||||
let rsp =
|
||||
<ResponseDocument<Cmd::Response, Ext::Response> as EppXml>::deserialize(&xml).unwrap();
|
||||
let rsp = xml::deserialize::<ResponseDocument<Cmd::Response, Ext::Response>>(&xml).unwrap();
|
||||
assert!(rsp.data.result.code.is_success());
|
||||
rsp.data
|
||||
}
|
||||
|
|
19
src/xml.rs
19
src/xml.rs
|
@ -6,25 +6,14 @@ use crate::error::Error;
|
|||
|
||||
pub const EPP_XML_HEADER: &str = r#"<?xml version="1.0" encoding="UTF-8" standalone="no"?>"#;
|
||||
|
||||
/// Trait to be implemented by serializers. Currently the only included serializer is `quick-xml`
|
||||
pub trait EppXml: Sized {
|
||||
/// Serializes the EppObject instance to an EPP XML document
|
||||
fn serialize(&self) -> Result<String, Error>
|
||||
where
|
||||
Self: Serialize,
|
||||
{
|
||||
pub(crate) fn serialize(doc: &impl Serialize) -> Result<String, Error> {
|
||||
Ok(format!(
|
||||
"{}\r\n{}",
|
||||
EPP_XML_HEADER,
|
||||
quick_xml::se::to_string(self).map_err(|e| Error::Xml(e.into()))?
|
||||
quick_xml::se::to_string(doc).map_err(|e| Error::Xml(e.into()))?
|
||||
))
|
||||
}
|
||||
|
||||
/// Deserializes an EPP XML document to an EppObject instance
|
||||
fn deserialize(epp_xml: &str) -> Result<Self, Error>
|
||||
where
|
||||
Self: DeserializeOwned + Sized,
|
||||
{
|
||||
quick_xml::de::from_str::<Self>(epp_xml).map_err(|e| Error::Xml(e.into()))
|
||||
}
|
||||
pub(crate) fn deserialize<T: DeserializeOwned>(xml: &str) -> Result<T, Error> {
|
||||
quick_xml::de::from_str(xml).map_err(|e| Error::Xml(e.into()))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue