2021-07-26 15:51:37 +00:00
|
|
|
//! Types for EPP requests
|
|
|
|
|
2021-12-09 09:17:00 +00:00
|
|
|
use serde::{de::DeserializeOwned, ser::SerializeStruct, ser::Serializer, Serialize};
|
2021-11-26 21:50:22 +00:00
|
|
|
use std::fmt::Debug;
|
2021-07-16 19:16:28 +00:00
|
|
|
|
2021-11-26 21:50:22 +00:00
|
|
|
use crate::{
|
2021-12-09 09:17:00 +00:00
|
|
|
common::{StringValue, EPP_XMLNS},
|
2021-12-08 15:38:58 +00:00
|
|
|
response::{Response, ResponseDocument, ResponseStatus},
|
2021-11-26 21:50:22 +00:00
|
|
|
xml::EppXml,
|
2021-12-22 09:55:48 +00:00
|
|
|
Error,
|
2021-11-26 21:50:22 +00:00
|
|
|
};
|
2021-07-16 19:16:28 +00:00
|
|
|
|
2021-11-26 19:36:28 +00:00
|
|
|
pub const EPP_VERSION: &str = "1.0";
|
|
|
|
pub const EPP_LANG: &str = "en";
|
|
|
|
|
2021-11-26 21:50:22 +00:00
|
|
|
/// Trait to set correct value for xml tags when tags are being generated from generic types
|
2021-12-09 09:17:00 +00:00
|
|
|
pub trait Transaction<Ext: Extension>: Command + Sized {
|
2021-11-26 21:50:22 +00:00
|
|
|
fn deserialize_response(
|
|
|
|
epp_xml: &str,
|
2021-12-22 09:55:48 +00:00
|
|
|
) -> Result<Response<Self::Response, Ext::Response>, Error> {
|
2021-12-09 09:17:00 +00:00
|
|
|
let rsp =
|
|
|
|
<ResponseDocument<Self::Response, Ext::Response> as EppXml>::deserialize(epp_xml)?;
|
2022-01-23 22:24:27 +00:00
|
|
|
match rsp.data.result.code.is_success() {
|
|
|
|
true => Ok(rsp.data),
|
|
|
|
false => Err(crate::error::Error::Command(ResponseStatus {
|
2021-12-02 13:13:42 +00:00
|
|
|
result: rsp.data.result,
|
|
|
|
tr_ids: rsp.data.tr_ids,
|
|
|
|
})),
|
2021-11-26 21:50:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-09 09:17:00 +00:00
|
|
|
pub trait Command: Serialize + Debug {
|
|
|
|
type Response: DeserializeOwned + Debug;
|
|
|
|
const COMMAND: &'static str;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Extension: Serialize + Debug {
|
2021-12-08 15:38:58 +00:00
|
|
|
type Response: DeserializeOwned + Debug;
|
2021-11-26 21:50:22 +00:00
|
|
|
}
|
|
|
|
|
2021-12-09 09:17:00 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2021-07-26 19:27:18 +00:00
|
|
|
/// Type corresponding to the <command> tag in an EPP XML request
|
2021-07-29 15:42:36 +00:00
|
|
|
/// with an <extension> tag
|
2022-03-12 16:32:24 +00:00
|
|
|
struct CommandWrapper<'a, D, E> {
|
2021-12-08 15:38:58 +00:00
|
|
|
pub command: &'static str,
|
2021-07-26 19:27:18 +00:00
|
|
|
/// The instance that will be used to populate the <command> tag
|
2021-12-07 18:19:05 +00:00
|
|
|
pub data: &'a D,
|
2021-07-26 15:51:37 +00:00
|
|
|
/// The client TRID
|
2021-12-07 18:19:05 +00:00
|
|
|
pub extension: Option<&'a E>,
|
2021-12-14 10:07:01 +00:00
|
|
|
pub client_tr_id: StringValue<'a>,
|
2021-07-25 14:34:01 +00:00
|
|
|
}
|
|
|
|
|
2021-12-07 18:19:05 +00:00
|
|
|
impl<'a, D: Serialize, E: Serialize> Serialize for CommandWrapper<'a, D, E> {
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Serializes the generic type T to the proper XML tag (set by the `#[element_name(name = <tagname>)]` attribute) for the request
|
2021-07-25 14:34:01 +00:00
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
where
|
|
|
|
S: Serializer,
|
|
|
|
{
|
2021-07-29 15:42:36 +00:00
|
|
|
let mut state = serializer.serialize_struct("command", 3)?;
|
2021-12-07 18:19:05 +00:00
|
|
|
state.serialize_field(self.command, self.data)?;
|
2021-07-29 15:42:36 +00:00
|
|
|
state.serialize_field("extension", &self.extension)?;
|
2021-07-25 14:34:01 +00:00
|
|
|
state.serialize_field("clTRID", &self.client_tr_id)?;
|
|
|
|
state.end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-09 09:17:00 +00:00
|
|
|
#[derive(Debug, PartialEq, Serialize)]
|
2021-12-08 15:38:58 +00:00
|
|
|
#[serde(rename = "epp")]
|
2022-03-12 16:32:24 +00:00
|
|
|
pub(crate) struct CommandDocument<'a, Cmd, Ext> {
|
2021-12-08 15:38:58 +00:00
|
|
|
xmlns: &'static str,
|
2022-03-12 16:32:24 +00:00
|
|
|
command: CommandWrapper<'a, Cmd, Ext>,
|
2021-12-08 15:38:58 +00:00
|
|
|
}
|
|
|
|
|
2022-03-12 16:32:24 +00:00
|
|
|
impl<'a, Cmd, Ext> CommandDocument<'a, Cmd, Ext> {
|
|
|
|
pub(crate) fn new(data: &'a Cmd, extension: Option<&'a Ext>, client_tr_id: &'a str) -> Self
|
|
|
|
where
|
|
|
|
Cmd: Transaction<Ext>,
|
|
|
|
Ext: Extension,
|
|
|
|
{
|
2021-12-08 15:38:58 +00:00
|
|
|
Self {
|
|
|
|
xmlns: EPP_XMLNS,
|
2022-03-12 16:32:24 +00:00
|
|
|
command: CommandWrapper {
|
|
|
|
command: Cmd::COMMAND,
|
|
|
|
data,
|
|
|
|
extension,
|
|
|
|
client_tr_id: client_tr_id.into(),
|
|
|
|
},
|
2021-07-29 15:42:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-08 15:38:58 +00:00
|
|
|
|
2021-12-07 18:19:05 +00:00
|
|
|
impl<'a, D: Serialize, E: Serialize> EppXml for CommandDocument<'a, D, E> {}
|