instant_epp/extensions/rgp/
report.rs

1//! Types for EPP RGP restore report
2
3use chrono::{DateTime, SecondsFormat, Utc};
4use instant_xml::ToXml;
5
6use crate::common::NoExtension;
7use crate::domain::update::DomainUpdate;
8use crate::request::{Extension, Transaction};
9
10use super::XMLNS;
11
12impl<'a> Transaction<Update<RgpRestoreReport<'a>>> for DomainUpdate<'a> {}
13
14impl<'a> RgpRestoreReport<'a> {
15    /// Create a new RGP restore report request
16    pub fn new(
17        pre_data: &'a str,
18        post_data: &'a str,
19        deleted_at: DateTime<Utc>,
20        restored_at: DateTime<Utc>,
21        restore_reason: &'a str,
22        statements: &'a [&'a str],
23        other: &'a str,
24    ) -> Self {
25        Self {
26            op: "report",
27            report: RgpRestoreReportSectionData {
28                pre_data,
29                post_data,
30                deleted_at: deleted_at.to_rfc3339_opts(SecondsFormat::AutoSi, true),
31                restored_at: restored_at.to_rfc3339_opts(SecondsFormat::AutoSi, true),
32                restore_reason,
33                statements,
34                other,
35            },
36        }
37    }
38}
39
40impl<'a> Extension for Update<RgpRestoreReport<'a>> {
41    type Response = NoExtension;
42}
43
44#[derive(Debug, ToXml)]
45#[xml(rename = "update", ns(XMLNS))]
46pub struct Update<T> {
47    pub data: T,
48}
49
50/// Type corresponding to the `<report>` section in the EPP rgp restore extension
51#[derive(Debug, ToXml)]
52#[xml(rename = "report", ns(XMLNS))]
53pub struct RgpRestoreReportSectionData<'a> {
54    /// The pre-delete registration date
55    #[xml(rename = "preData")]
56    pre_data: &'a str,
57    /// The post-delete registration date
58    #[xml(rename = "postData")]
59    post_data: &'a str,
60    /// The domain deletion date
61    #[xml(rename = "delTime")]
62    deleted_at: String,
63    /// The domain restore request date
64    #[xml(rename = "resTime")]
65    restored_at: String,
66    /// The reason for domain restoration
67    #[xml(rename = "resReason")]
68    restore_reason: &'a str,
69    /// The registrar's statements on the domain restoration
70    #[xml(rename = "statement")]
71    statements: &'a [&'a str],
72    /// Other remarks for domain restoration
73    #[xml(rename = "other")]
74    other: &'a str,
75}
76
77#[derive(Debug, ToXml)]
78/// Type for EPP XML `<check>` command for domains
79#[xml(rename = "restore", ns(XMLNS))]
80pub struct RgpRestoreReport<'a> {
81    /// The value of the op attribute for the `<restore>` tag
82    #[xml(attribute)]
83    op: &'a str,
84    /// Data for the `<report>` tag
85    #[xml(rename = "rgp:report")]
86    report: RgpRestoreReportSectionData<'a>,
87}
88
89#[cfg(test)]
90mod tests {
91    use std::str::FromStr;
92
93    use chrono::DateTime;
94
95    use super::{RgpRestoreReport, Update};
96    use crate::domain::update::{DomainChangeInfo, DomainUpdate};
97    use crate::tests::assert_serialized;
98
99    #[test]
100    fn command() {
101        let pre_data =
102            "Pre-delete registration data goes here. Both XML and free text are allowed.";
103        let post_data =
104            "Post-restore registration data goes here. Both XML and free text are allowed.";
105        let deleted_at = DateTime::from_str("2021-07-10T22:00:00.0Z").unwrap();
106        let restored_at = DateTime::from_str("2021-07-20T22:00:00.0Z").unwrap();
107        let restore_reason = "Registrant error.";
108        let statements = &[
109            "This registrar has not restored the Registered Name in order to assume the rights to use or sell the Registered Name for itself or for any third party.",
110            "The information in this report is true to best of this registrar's knowledge, and this registrar acknowledges that intentionally supplying false information in this report shall constitute an incurable material breach of the Registry-Registrar Agreement.",
111        ];
112        let other = "Supporting information goes here.";
113
114        let domain_restore_report = Update {
115            data: RgpRestoreReport::new(
116                pre_data,
117                post_data,
118                deleted_at,
119                restored_at,
120                restore_reason,
121                statements,
122                other,
123            ),
124        };
125
126        let mut object = DomainUpdate::new("eppdev.com");
127        object.info(DomainChangeInfo {
128            registrant: None,
129            auth_info: None,
130        });
131
132        assert_serialized(
133            "request/extensions/rgp_restore_report.xml",
134            (&object, &domain_restore_report),
135        );
136    }
137}