epp_client/host/
update.rs

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