Flatten XML abstraction

This commit is contained in:
Dirkjan Ochtman 2022-03-12 20:36:46 +01:00 committed by masalachai
parent 3f91647370
commit ca19e545fd
6 changed files with 28 additions and 57 deletions

View File

@ -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> {

View File

@ -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!(

View File

@ -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> {}

View File

@ -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 &lt;response&gt; tag in an EPP response XML
/// without <msgQ> or &lt;resData&gt; 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());

View File

@ -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
}

View File

@ -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,
{
Ok(format!(
"{}\r\n{}",
EPP_XML_HEADER,
quick_xml::se::to_string(self).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 serialize(doc: &impl Serialize) -> Result<String, Error> {
Ok(format!(
"{}\r\n{}",
EPP_XML_HEADER,
quick_xml::se::to_string(doc).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()))
}