Replace HostAddr with IpAddr in the public interface
This commit is contained in:
parent
1426312df0
commit
cdbf0a2e65
|
@ -1,7 +1,8 @@
|
|||
//! Common data types included in EPP Requests and Responses
|
||||
|
||||
use std::{borrow::Cow, fmt::Display};
|
||||
use std::{borrow::Cow, fmt::Display, net::IpAddr};
|
||||
|
||||
use serde::ser::SerializeSeq;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::request::Extension;
|
||||
|
@ -148,37 +149,42 @@ pub struct Services<'a> {
|
|||
|
||||
/// The <hostAddr> types domain or host transactions
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct HostAddr<'a> {
|
||||
pub(crate) struct HostAddr<'a> {
|
||||
#[serde(rename = "ip")]
|
||||
pub ip_version: Option<Cow<'a, str>>,
|
||||
#[serde(rename = "$value")]
|
||||
pub address: Cow<'a, str>,
|
||||
}
|
||||
|
||||
impl<'a> HostAddr<'a> {
|
||||
/// Creates a 'v4' type HostAddr (mostly useful when you don't want to include an 'ip' attr in the XML)
|
||||
pub fn new(ip_version: &'a str, address: &'a str) -> Self {
|
||||
impl From<&IpAddr> for HostAddr<'static> {
|
||||
fn from(addr: &IpAddr) -> Self {
|
||||
Self {
|
||||
ip_version: Some(ip_version.into()),
|
||||
address: address.into(),
|
||||
ip_version: Some(match addr {
|
||||
IpAddr::V4(_) => "v4".into(),
|
||||
IpAddr::V6(_) => "v6".into(),
|
||||
}),
|
||||
address: addr.to_string().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a 'v4' type HostAddr
|
||||
pub fn new_v4(address: &'a str) -> HostAddr {
|
||||
HostAddr {
|
||||
ip_version: Some("v4".into()),
|
||||
address: address.into(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn serialize_host_addrs_option<T: AsRef<[IpAddr]>, S>(
|
||||
addrs: &Option<T>,
|
||||
ser: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::ser::Serializer,
|
||||
{
|
||||
let addrs = match addrs {
|
||||
Some(addrs) => addrs.as_ref(),
|
||||
None => return ser.serialize_none(),
|
||||
};
|
||||
|
||||
/// Creates a 'v6' type HostAddr
|
||||
pub fn new_v6(address: &'a str) -> HostAddr {
|
||||
HostAddr {
|
||||
ip_version: Some("v6".into()),
|
||||
address: address.into(),
|
||||
}
|
||||
let mut seq = ser.serialize_seq(Some(addrs.len()))?;
|
||||
for addr in addrs {
|
||||
seq.serialize_element(&HostAddr::from(addr))?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
|
||||
/// The <status> type on contact transactions
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use std::borrow::Cow;
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::common::{HostAddr, StringValue};
|
||||
use crate::common::{serialize_host_addrs_option, HostAddr, StringValue};
|
||||
use crate::Error;
|
||||
|
||||
pub mod check;
|
||||
|
@ -35,8 +37,34 @@ pub struct HostAttr<'a> {
|
|||
#[serde(rename = "domain:hostName", alias = "hostName")]
|
||||
pub name: StringValue<'a>,
|
||||
/// The <hostAddr> tags
|
||||
#[serde(rename = "domain:hostAddr", alias = "hostAddr")]
|
||||
pub addresses: Option<Vec<HostAddr<'a>>>,
|
||||
#[serde(
|
||||
rename = "domain:hostAddr",
|
||||
alias = "hostAddr",
|
||||
serialize_with = "serialize_host_addrs_option",
|
||||
deserialize_with = "deserialize_host_addrs_option"
|
||||
)]
|
||||
pub addresses: Option<Vec<IpAddr>>,
|
||||
}
|
||||
|
||||
fn deserialize_host_addrs_option<'de, D>(de: D) -> Result<Option<Vec<IpAddr>>, D::Error>
|
||||
where
|
||||
D: serde::de::Deserializer<'de>,
|
||||
{
|
||||
let addrs = Option::<Vec<HostAddr<'static>>>::deserialize(de)?;
|
||||
let addrs = match addrs {
|
||||
Some(addrs) => addrs,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let result = addrs
|
||||
.into_iter()
|
||||
.map(|addr| IpAddr::from_str(&addr.address))
|
||||
.collect::<Result<_, _>>();
|
||||
|
||||
match result {
|
||||
Ok(addrs) => Ok(Some(addrs)),
|
||||
Err(e) => Err(serde::de::Error::custom(format!("{}", e))),
|
||||
}
|
||||
}
|
||||
|
||||
/// The list of <hostAttr> types for domain transactions. Typically under an <ns> tag
|
||||
|
|
|
@ -104,11 +104,12 @@ pub struct DomainCreateResponse {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{DomainContact, DomainCreate, HostList, Period};
|
||||
use crate::common::{HostAddr, NoExtension};
|
||||
use crate::common::NoExtension;
|
||||
use crate::domain::{HostAttr, HostAttrList, HostObjList};
|
||||
use crate::request::Transaction;
|
||||
use crate::response::ResultCode;
|
||||
use crate::tests::{get_xml, CLTRID, SUCCESS_MSG, SVTRID};
|
||||
use std::net::IpAddr;
|
||||
|
||||
#[test]
|
||||
fn command() {
|
||||
|
@ -208,8 +209,8 @@ mod tests {
|
|||
HostAttr {
|
||||
name: "ns2.eppdev-1.com".into(),
|
||||
addresses: Some(vec![
|
||||
HostAddr::new_v4("177.232.12.58"),
|
||||
HostAddr::new_v6("2404:6800:4001:801::200e"),
|
||||
IpAddr::from([177, 232, 12, 58]),
|
||||
IpAddr::from([0x2404, 0x6800, 0x4001, 0x801, 0, 0, 0, 0x200e]),
|
||||
]),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
//! Types for EPP host create request
|
||||
|
||||
use std::net::IpAddr;
|
||||
|
||||
use super::XMLNS;
|
||||
use crate::common::{HostAddr, NoExtension, StringValue};
|
||||
use crate::common::{serialize_host_addrs_option, NoExtension, StringValue};
|
||||
use crate::request::{Command, Transaction};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -13,7 +15,7 @@ impl<'a> Command for HostCreate<'a> {
|
|||
}
|
||||
|
||||
impl<'a> HostCreate<'a> {
|
||||
pub fn new(host: &'a str, addresses: Option<&'a [HostAddr]>) -> Self {
|
||||
pub fn new(host: &'a str, addresses: Option<&'a [IpAddr]>) -> Self {
|
||||
Self {
|
||||
host: HostCreateRequestData {
|
||||
xmlns: XMLNS,
|
||||
|
@ -36,8 +38,8 @@ pub struct HostCreateRequestData<'a> {
|
|||
#[serde(rename = "host:name")]
|
||||
pub name: StringValue<'a>,
|
||||
/// The list of IP addresses for the host
|
||||
#[serde(rename = "host:addr")]
|
||||
pub addresses: Option<&'a [HostAddr<'a>]>,
|
||||
#[serde(rename = "host:addr", serialize_with = "serialize_host_addrs_option")]
|
||||
pub addresses: Option<&'a [IpAddr]>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
|
@ -70,8 +72,8 @@ pub struct HostCreateResponse {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::HostCreate;
|
||||
use crate::common::{HostAddr, NoExtension};
|
||||
use super::{HostCreate, IpAddr};
|
||||
use crate::common::NoExtension;
|
||||
use crate::request::Transaction;
|
||||
use crate::response::ResultCode;
|
||||
use crate::tests::{get_xml, CLTRID, SUCCESS_MSG, SVTRID};
|
||||
|
@ -81,8 +83,8 @@ mod tests {
|
|||
let xml = get_xml("request/host/create.xml").unwrap();
|
||||
|
||||
let addresses = &[
|
||||
HostAddr::new("v4", "29.245.122.14"),
|
||||
HostAddr::new("v6", "2404:6800:4001:801::200e"),
|
||||
IpAddr::from([29, 245, 122, 14]),
|
||||
IpAddr::from([0x2404, 0x6800, 0x4001, 0x801, 0, 0, 0, 0x200e]),
|
||||
];
|
||||
|
||||
let object = HostCreate::new("host1.eppdev-1.com", Some(addresses));
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
//! Types for EPP host info request
|
||||
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::XMLNS;
|
||||
use crate::common::{HostAddr, NoExtension, ObjectStatus, StringValue};
|
||||
use crate::request::{Command, Transaction};
|
||||
|
@ -57,8 +60,8 @@ pub struct HostInfoResponseData {
|
|||
#[serde(rename = "status")]
|
||||
pub statuses: Vec<ObjectStatus<'static>>,
|
||||
/// The list of host IP addresses
|
||||
#[serde(rename = "addr")]
|
||||
pub addresses: Vec<HostAddr<'static>>,
|
||||
#[serde(rename = "addr", deserialize_with = "deserialize_host_addrs")]
|
||||
pub addresses: Vec<IpAddr>,
|
||||
/// The epp user to whom the host belongs
|
||||
#[serde(rename = "clID")]
|
||||
pub client_id: StringValue<'static>,
|
||||
|
@ -79,6 +82,18 @@ pub struct HostInfoResponseData {
|
|||
pub transferred_at: Option<StringValue<'static>>,
|
||||
}
|
||||
|
||||
fn deserialize_host_addrs<'de, D>(de: D) -> Result<Vec<IpAddr>, D::Error>
|
||||
where
|
||||
D: serde::de::Deserializer<'de>,
|
||||
{
|
||||
let addrs = Vec::<HostAddr<'static>>::deserialize(de)?;
|
||||
addrs
|
||||
.into_iter()
|
||||
.map(|addr| IpAddr::from_str(&addr.address))
|
||||
.collect::<Result<_, _>>()
|
||||
.map_err(|e| serde::de::Error::custom(format!("{}", e)))
|
||||
}
|
||||
|
||||
/// Type that represents the <resData> tag for host info response
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct HostInfoResponse {
|
||||
|
@ -89,7 +104,7 @@ pub struct HostInfoResponse {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::HostInfo;
|
||||
use super::{HostInfo, IpAddr};
|
||||
use crate::common::NoExtension;
|
||||
use crate::request::Transaction;
|
||||
use crate::response::ResultCode;
|
||||
|
@ -122,20 +137,12 @@ mod tests {
|
|||
assert_eq!(result.info_data.roid, "UNDEF-ROID".into());
|
||||
assert_eq!(result.info_data.statuses[0].status, "ok".to_string());
|
||||
assert_eq!(
|
||||
*(result.info_data.addresses[0].ip_version.as_ref().unwrap()),
|
||||
"v4".to_string()
|
||||
result.info_data.addresses[0],
|
||||
IpAddr::from([29, 245, 122, 14])
|
||||
);
|
||||
assert_eq!(
|
||||
result.info_data.addresses[0].address,
|
||||
"29.245.122.14".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
*(result.info_data.addresses[1].ip_version.as_ref().unwrap()),
|
||||
"v6".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
result.info_data.addresses[1].address,
|
||||
"2404:6800:4001:0801:0000:0000:0000:200e".to_string()
|
||||
result.info_data.addresses[1],
|
||||
IpAddr::from([0x2404, 0x6800, 0x4001, 0x801, 0, 0, 0, 0x200e])
|
||||
);
|
||||
assert_eq!(result.info_data.client_id, "eppdev".into());
|
||||
assert_eq!(result.info_data.creator_id, "creator".into());
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
//! Types for EPP host update request
|
||||
|
||||
use std::net::IpAddr;
|
||||
|
||||
use super::XMLNS;
|
||||
use crate::common::{HostAddr, NoExtension, ObjectStatus, StringValue};
|
||||
use crate::common::{serialize_host_addrs_option, NoExtension, ObjectStatus, StringValue};
|
||||
use crate::request::{Command, Transaction};
|
||||
use serde::Serialize;
|
||||
|
||||
|
@ -53,8 +55,8 @@ pub struct HostChangeInfo<'a> {
|
|||
#[derive(Serialize, Debug)]
|
||||
pub struct HostAddRemove<'a> {
|
||||
/// The IP addresses to be added to or removed from the host
|
||||
#[serde(rename = "host:addr")]
|
||||
pub addresses: Option<&'a [HostAddr<'a>]>,
|
||||
#[serde(rename = "host:addr", serialize_with = "serialize_host_addrs_option")]
|
||||
pub addresses: Option<&'a [IpAddr]>,
|
||||
/// The statuses to be added to or removed from the host
|
||||
#[serde(rename = "host:status")]
|
||||
pub statuses: Option<&'a [ObjectStatus<'a>]>,
|
||||
|
@ -90,8 +92,9 @@ pub struct HostUpdate<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::IpAddr;
|
||||
use super::{HostAddRemove, HostChangeInfo, HostUpdate};
|
||||
use crate::common::{HostAddr, NoExtension, ObjectStatus};
|
||||
use crate::common::{NoExtension, ObjectStatus};
|
||||
use crate::request::Transaction;
|
||||
use crate::response::ResultCode;
|
||||
use crate::tests::{get_xml, CLTRID, SUCCESS_MSG, SVTRID};
|
||||
|
@ -100,7 +103,9 @@ mod tests {
|
|||
fn command() {
|
||||
let xml = get_xml("request/host/update.xml").unwrap();
|
||||
|
||||
let addr = &[HostAddr::new("v6", "2404:6800:4001:801::200e")];
|
||||
let addr = &[IpAddr::from([
|
||||
0x2404, 0x6800, 0x4001, 0x801, 0, 0, 0, 0x200e,
|
||||
])];
|
||||
|
||||
let add = HostAddRemove {
|
||||
addresses: Some(addr),
|
||||
|
|
|
@ -55,6 +55,7 @@ mod tests {
|
|||
use crate::request::Transaction;
|
||||
use crate::response::ResultCode;
|
||||
use crate::tests::{get_xml, CLTRID, SVTRID};
|
||||
use std::net::IpAddr;
|
||||
|
||||
#[test]
|
||||
fn command() {
|
||||
|
@ -142,7 +143,10 @@ mod tests {
|
|||
|
||||
assert_eq!(host.roid, "1234".into());
|
||||
assert!(host.statuses.iter().any(|s| s.status == "ok"));
|
||||
assert!(host.addresses.iter().any(|a| a.address == *"1.1.1.1"));
|
||||
assert!(host
|
||||
.addresses
|
||||
.iter()
|
||||
.any(|a| a == &IpAddr::from([1, 1, 1, 1])));
|
||||
assert_eq!(host.client_id, "1234".into());
|
||||
assert_eq!(host.creator_id, "user".into());
|
||||
assert_eq!(host.created_at, "2021-12-01T22:40:48Z".into());
|
||||
|
|
Loading…
Reference in New Issue