1use std::ops::Deref;
4use std::{borrow::Cow, fmt::Display, net::IpAddr};
5
6use serde::ser::SerializeSeq;
7use serde::{Deserialize, Serialize};
8
9use crate::request::Extension;
10
11pub(crate) const EPP_XMLNS: &str = "urn:ietf:params:xml:ns:epp-1.0";
12
13#[derive(Default, Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
16pub struct StringValue<'a>(Cow<'a, str>);
17
18impl Deref for StringValue<'_> {
19 type Target = str;
20
21 fn deref(&self) -> &Self::Target {
22 self.0.as_ref()
23 }
24}
25
26impl<'a> AsRef<str> for StringValue<'a> {
27 fn as_ref(&self) -> &str {
28 self.0.as_ref()
29 }
30}
31
32impl Display for StringValue<'_> {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 write!(f, "{}", self.0)
35 }
36}
37
38impl<'a> From<&'a str> for StringValue<'a> {
39 fn from(s: &'a str) -> Self {
40 Self(s.into())
41 }
42}
43
44impl From<String> for StringValue<'static> {
45 fn from(s: String) -> Self {
46 Self(s.into())
47 }
48}
49
50#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
51pub struct NoExtension;
53
54impl Extension for NoExtension {
55 type Response = NoExtension;
56}
57
58#[derive(Deserialize, Debug)]
60struct Available {
61 #[serde(rename = "$value")]
63 pub id: StringValue<'static>,
64 #[serde(rename = "avail")]
66 pub available: bool,
67}
68
69#[derive(Deserialize, Debug)]
71struct CheckResponseDataItem {
72 #[serde(rename = "name", alias = "id")]
74 pub resource: Available,
75 pub reason: Option<StringValue<'static>>,
77}
78
79#[derive(Deserialize, Debug)]
81struct CheckData {
82 #[serde(rename = "cd")]
84 pub list: Vec<CheckResponseDataItem>,
85}
86
87#[derive(Deserialize, Debug)]
89struct DeserializedCheckResponse {
90 #[serde(rename = "chkData")]
92 pub check_data: CheckData,
93}
94
95#[derive(Debug)]
96pub struct Checked {
97 pub id: String,
98 pub available: bool,
99 pub reason: Option<String>,
100}
101
102#[derive(Deserialize, Debug)]
103#[serde(from = "DeserializedCheckResponse")]
104pub struct CheckResponse {
105 pub list: Vec<Checked>,
106}
107
108impl From<DeserializedCheckResponse> for CheckResponse {
109 fn from(rsp: DeserializedCheckResponse) -> Self {
110 Self {
111 list: rsp
112 .check_data
113 .list
114 .into_iter()
115 .map(|item| Checked {
116 id: item.resource.id.0.into_owned(),
117 available: item.resource.available,
118 reason: item.reason.map(|r| r.0.into_owned()),
119 })
120 .collect(),
121 }
122 }
123}
124
125#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
127#[serde(rename = "options")]
128pub struct Options<'a> {
129 pub version: StringValue<'a>,
131 pub lang: StringValue<'a>,
133}
134
135impl<'a> Options<'a> {
136 pub fn build(version: &'a str, lang: &'a str) -> Self {
138 Self {
139 version: version.into(),
140 lang: lang.into(),
141 }
142 }
143}
144
145#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
147#[serde(rename = "svcExtension")]
148pub struct ServiceExtension<'a> {
149 #[serde(rename = "extURI")]
151 pub ext_uris: Option<Vec<StringValue<'a>>>,
152}
153
154#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
156pub struct Services<'a> {
157 #[serde(rename = "objURI")]
159 pub obj_uris: Vec<StringValue<'a>>,
160 #[serde(rename = "svcExtension")]
162 pub svc_ext: Option<ServiceExtension<'a>>,
163}
164
165#[derive(Serialize, Deserialize, Debug)]
167pub(crate) struct HostAddr<'a> {
168 #[serde(rename = "ip")]
169 pub ip_version: Option<Cow<'a, str>>,
170 #[serde(rename = "$value")]
171 pub address: Cow<'a, str>,
172}
173
174impl From<&IpAddr> for HostAddr<'static> {
175 fn from(addr: &IpAddr) -> Self {
176 Self {
177 ip_version: Some(match addr {
178 IpAddr::V4(_) => "v4".into(),
179 IpAddr::V6(_) => "v6".into(),
180 }),
181 address: addr.to_string().into(),
182 }
183 }
184}
185
186pub(crate) fn serialize_host_addrs_option<T: AsRef<[IpAddr]>, S>(
187 addrs: &Option<T>,
188 ser: S,
189) -> Result<S::Ok, S::Error>
190where
191 S: serde::ser::Serializer,
192{
193 let addrs = match addrs {
194 Some(addrs) => addrs.as_ref(),
195 None => return ser.serialize_none(),
196 };
197
198 let mut seq = ser.serialize_seq(Some(addrs.len()))?;
199 for addr in addrs {
200 seq.serialize_element(&HostAddr::from(addr))?;
201 }
202 seq.end()
203}
204
205#[derive(Serialize, Deserialize, Debug)]
207pub struct ObjectStatus<'a> {
208 #[serde(rename = "s")]
210 pub status: Cow<'a, str>,
211}
212
213pub struct Certificate(pub Vec<u8>);
217
218pub struct PrivateKey(pub Vec<u8>);