instant_epp/contact/
check.rs

1//! Types for EPP contact check request
2
3use std::fmt::{self, Debug};
4
5use instant_xml::{FromXml, Serializer, ToXml};
6
7use super::XMLNS;
8use crate::common::{NoExtension, EPP_XMLNS};
9use crate::request::{Command, Transaction};
10
11impl<'a> Transaction<NoExtension> for ContactCheck<'a> {}
12
13impl<'a> Command for ContactCheck<'a> {
14    type Response = CheckData;
15    const COMMAND: &'static str = "check";
16}
17
18// Request
19
20/// Type that represents the `<check>` command for contact transactions
21#[derive(Debug, ToXml)]
22#[xml(rename = "check", ns(XMLNS))]
23struct ContactList<'a> {
24    /// The list of contact ids to check for availability
25    id: &'a [&'a str],
26}
27
28fn serialize_contacts<W: fmt::Write + ?Sized>(
29    ids: &[&str],
30    serializer: &mut Serializer<W>,
31) -> Result<(), instant_xml::Error> {
32    ContactList { id: ids }.serialize(None, serializer)
33}
34
35/// The EPP `check` command for contacts
36#[derive(Clone, Debug, ToXml)]
37#[xml(rename = "check", ns(EPP_XMLNS))]
38pub struct ContactCheck<'a> {
39    #[xml(serialize_with = "serialize_contacts")]
40    pub contact_ids: &'a [&'a str],
41}
42
43// Response
44
45#[derive(Debug, FromXml)]
46#[xml(rename = "id", ns(XMLNS))]
47pub struct Checked {
48    #[xml(attribute, rename = "avail")]
49    pub available: bool,
50    #[xml(attribute)]
51    pub reason: Option<String>,
52    #[xml(direct)]
53    pub id: String,
54}
55
56#[derive(Debug, FromXml)]
57#[xml(rename = "cd", ns(XMLNS))]
58pub struct CheckedContact {
59    /// Data under the `<cd>` tag
60    pub inner: Checked,
61}
62
63/// Type that represents the `<chkData>` tag for host check response
64#[derive(Debug, FromXml)]
65#[xml(rename = "chkData", ns(XMLNS))]
66pub struct CheckData {
67    pub list: Vec<CheckedContact>,
68}
69
70#[cfg(test)]
71mod tests {
72    use super::ContactCheck;
73    use crate::response::ResultCode;
74    use crate::tests::{assert_serialized, response_from_file, CLTRID, SUCCESS_MSG, SVTRID};
75
76    #[test]
77    fn command() {
78        let object = ContactCheck {
79            contact_ids: &["eppdev-contact-1", "eppdev-contact-2"],
80        };
81        assert_serialized("request/contact/check.xml", &object);
82    }
83
84    #[test]
85    fn response() {
86        let object = response_from_file::<ContactCheck>("response/contact/check.xml");
87        let results = object.res_data().unwrap();
88
89        assert_eq!(object.result.code, ResultCode::CommandCompletedSuccessfully);
90        assert_eq!(object.result.message, SUCCESS_MSG);
91        assert_eq!(results.list[0].inner.id, "eppdev-contact-1");
92        assert!(!results.list[0].inner.available);
93        assert_eq!(results.list[1].inner.id, "eppdev-contact-2");
94        assert!(results.list[1].inner.available);
95        assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
96        assert_eq!(object.tr_ids.server_tr_id, SVTRID);
97    }
98}