instant_epp/host/
update.rs

1//! Types for EPP host update request
2
3use std::net::IpAddr;
4
5use instant_xml::ToXml;
6
7use super::{serialize_host_addrs_option, Status, XMLNS};
8use crate::common::{NoExtension, EPP_XMLNS};
9use crate::request::{Command, Transaction};
10
11impl<'a> Transaction<NoExtension> for HostUpdate<'a> {}
12
13impl<'a> Command for HostUpdate<'a> {
14    type Response = ();
15    const COMMAND: &'static str = "update";
16}
17
18impl<'a> HostUpdate<'a> {
19    pub fn new(name: &'a str) -> Self {
20        Self {
21            host: HostUpdateRequest {
22                name,
23                add: None,
24                remove: None,
25                change_info: None,
26            },
27        }
28    }
29
30    /// Sets the data for the `<chg>` element of the host update
31    pub fn info(&mut self, info: HostChangeInfo<'a>) {
32        self.host.change_info = Some(info);
33    }
34
35    /// Sets the data for the `<add>` element of the host update
36    pub fn add(&mut self, add: HostAdd<'a>) {
37        self.host.add = Some(add);
38    }
39
40    /// Sets the data for the `<rem>` element of the host update
41    pub fn remove(&mut self, remove: HostRemove<'a>) {
42        self.host.remove = Some(remove);
43    }
44}
45
46/// Type for data under the `<chg>` tag
47#[derive(Debug, ToXml)]
48#[xml(rename = "chg", ns(XMLNS))]
49pub struct HostChangeInfo<'a> {
50    /// The new name for the host
51    pub name: &'a str,
52}
53
54/// Type for data under the `<add>` and `<rem>` tags
55#[derive(Debug, ToXml)]
56#[xml(rename = "add", ns(XMLNS))]
57pub struct HostAdd<'a> {
58    /// The IP addresses to be added to or removed from the host
59    #[xml(rename = "host:addr", serialize_with = "serialize_host_addrs_option")]
60    pub addresses: Option<&'a [IpAddr]>,
61    /// The statuses to be added to or removed from the host
62    #[xml(rename = "host:status")]
63    pub statuses: Option<&'a [Status]>,
64}
65
66/// Type for data under the `<add>` and `<rem>` tags
67#[derive(Debug, ToXml)]
68#[xml(rename = "rem", ns(XMLNS))]
69pub struct HostRemove<'a> {
70    /// The IP addresses to be added to or removed from the host
71    #[xml(rename = "host:addr", serialize_with = "serialize_host_addrs_option")]
72    pub addresses: Option<&'a [IpAddr]>,
73    /// The statuses to be added to or removed from the host
74    #[xml(rename = "host:status")]
75    pub statuses: Option<&'a [Status]>,
76}
77
78/// Type for data under the host `<update>` tag
79#[derive(Debug, ToXml)]
80#[xml(rename = "update", ns(XMLNS))]
81pub struct HostUpdateRequest<'a> {
82    /// The name of the host
83    name: &'a str,
84    /// The IP addresses and statuses to be added to the host
85    #[xml(rename = "host:add")]
86    add: Option<HostAdd<'a>>,
87    /// The IP addresses and statuses to be removed from the host
88    #[xml(rename = "host:rem")]
89    remove: Option<HostRemove<'a>>,
90    /// The host details that need to be updated
91    #[xml(rename = "host:chg")]
92    change_info: Option<HostChangeInfo<'a>>,
93}
94
95/// Type for EPP XML `<update>` command for hosts
96#[derive(Debug, ToXml)]
97#[xml(rename = "update", ns(EPP_XMLNS))]
98pub struct HostUpdate<'a> {
99    /// The instance holding the data for the host to be updated
100    host: HostUpdateRequest<'a>,
101}
102
103#[cfg(test)]
104mod tests {
105    use super::IpAddr;
106    use super::{HostAdd, HostChangeInfo, HostRemove, HostUpdate, Status};
107    use crate::response::ResultCode;
108    use crate::tests::{assert_serialized, response_from_file, CLTRID, SUCCESS_MSG, SVTRID};
109
110    #[test]
111    fn command() {
112        let addr = &[IpAddr::from([
113            0x2404, 0x6800, 0x4001, 0x801, 0, 0, 0, 0x200e,
114        ])];
115
116        let add = HostAdd {
117            addresses: Some(addr),
118            statuses: None,
119        };
120
121        let remove = HostRemove {
122            addresses: None,
123            statuses: Some(&[Status::ClientDeleteProhibited]),
124        };
125
126        let mut object = HostUpdate::new("host1.eppdev-1.com");
127
128        object.add(add);
129        object.remove(remove);
130        object.info(HostChangeInfo {
131            name: "host2.eppdev-1.com",
132        });
133
134        assert_serialized("request/host/update.xml", &object);
135    }
136
137    #[test]
138    fn response() {
139        let object = response_from_file::<HostUpdate>("response/host/update.xml");
140
141        assert_eq!(object.result.code, ResultCode::CommandCompletedSuccessfully);
142        assert_eq!(object.result.message, SUCCESS_MSG);
143        assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
144        assert_eq!(object.tr_ids.server_tr_id, SVTRID);
145    }
146}