epp_client/
contact.rs

1use std::borrow::Cow;
2use std::str::FromStr;
3
4use serde::{Deserialize, Serialize};
5
6use crate::common::StringValue;
7
8pub mod check;
9pub use check::ContactCheck;
10
11pub mod create;
12pub use create::ContactCreate;
13
14pub mod delete;
15pub use delete::ContactDelete;
16
17pub mod info;
18pub use info::ContactInfo;
19
20pub mod update;
21pub use update::ContactUpdate;
22
23pub const XMLNS: &str = "urn:ietf:params:xml:ns:contact-1.0";
24
25#[derive(Serialize, Deserialize, Debug, Clone)]
26pub struct Country(celes::Country);
27
28impl FromStr for Country {
29    type Err = <celes::Country as FromStr>::Err;
30
31    fn from_str(s: &str) -> Result<Self, Self::Err> {
32        Ok(Self(celes::Country::from_str(s)?))
33    }
34}
35
36impl std::ops::Deref for Country {
37    type Target = celes::Country;
38
39    fn deref(&self) -> &Self::Target {
40        &self.0
41    }
42}
43
44/// The &lt;authInfo&gt; tag for domain and contact transactions
45#[derive(Serialize, Deserialize, Debug, Clone)]
46pub struct ContactAuthInfo<'a> {
47    /// The &lt;pw&gt; tag under &lt;authInfo&gt;
48    #[serde(rename = "contact:pw", alias = "pw")]
49    pub password: StringValue<'a>,
50}
51
52impl<'a> ContactAuthInfo<'a> {
53    /// Creates a ContactAuthInfo instance with the given password
54    pub fn new(password: &'a str) -> Self {
55        Self {
56            password: password.into(),
57        }
58    }
59}
60
61/// The data for &lt;voice&gt; and &lt;fax&gt; types on domain transactions
62#[derive(Serialize, Deserialize, Debug, Clone)]
63pub struct Phone<'a> {
64    /// The inner text on the &lt;voice&gt; and &lt;fax&gt; tags
65    #[serde(rename = "$value")]
66    pub number: Cow<'a, str>,
67    /// The value of the 'x' attr on &lt;voice&gt; and &lt;fax&gt; tags
68    #[serde(rename = "x")]
69    pub extension: Option<Cow<'a, str>>,
70}
71
72impl<'a> Phone<'a> {
73    /// Creates a new Phone instance with a given phone number
74    pub fn new(number: &'a str) -> Self {
75        Self {
76            extension: None,
77            number: number.into(),
78        }
79    }
80
81    /// Sets the extension value of the Phone type
82    pub fn set_extension(&mut self, ext: &'a str) {
83        self.extension = Some(ext.into());
84    }
85}
86
87/// The &lt;addr&gt; type on contact transactions
88#[derive(Serialize, Deserialize, Debug, Clone)]
89pub struct Address<'a> {
90    /// The &lt;street&gt; tags under &lt;addr&gt;
91    #[serde(rename = "contact:street", alias = "street")]
92    pub street: Vec<StringValue<'a>>,
93    /// The &lt;city&gt; tag under &lt;addr&gt;
94    #[serde(rename = "contact:city", alias = "city")]
95    pub city: StringValue<'a>,
96    /// The &lt;sp&gt; tag under &lt;addr&gt;
97    #[serde(rename = "contact:sp", alias = "sp")]
98    pub province: StringValue<'a>,
99    /// The &lt;pc&gt; tag under &lt;addr&gt;
100    #[serde(rename = "contact:pc", alias = "pc")]
101    pub postal_code: StringValue<'a>,
102    /// The &lt;cc&gt; tag under &lt;addr&gt;
103    #[serde(rename = "contact:cc", alias = "cc")]
104    pub country: Country,
105}
106
107impl<'a> Address<'a> {
108    /// Creates a new Address instance
109    pub fn new(
110        street: &[&'a str],
111        city: &'a str,
112        province: &'a str,
113        postal_code: &'a str,
114        country: Country,
115    ) -> Self {
116        let street = street.iter().map(|&s| s.into()).collect();
117
118        Self {
119            street,
120            city: city.into(),
121            province: province.into(),
122            postal_code: postal_code.into(),
123            country,
124        }
125    }
126}
127
128/// The &lt;postalInfo&gt; type on contact transactions
129#[derive(Serialize, Deserialize, Debug, Clone)]
130pub struct PostalInfo<'a> {
131    /// The 'type' attr on &lt;postalInfo&gt;
132    #[serde(rename = "type")]
133    pub info_type: String,
134    /// The &lt;name&gt; tag under &lt;postalInfo&gt;
135    #[serde(rename = "contact:name", alias = "name")]
136    pub name: StringValue<'a>,
137    /// The &lt;org&gt; tag under &lt;postalInfo&gt;
138    #[serde(rename = "contact:org", alias = "org")]
139    pub organization: StringValue<'a>,
140    /// The &lt;addr&gt; tag under &lt;postalInfo&gt;
141    #[serde(rename = "contact:addr", alias = "addr")]
142    pub address: Address<'a>,
143}
144
145impl<'a> PostalInfo<'a> {
146    /// Creates a new PostalInfo instance
147    pub fn new(
148        info_type: &str,
149        name: &'a str,
150        organization: &'a str,
151        address: Address<'a>,
152    ) -> Self {
153        Self {
154            info_type: info_type.to_string(),
155            name: name.into(),
156            organization: organization.into(),
157            address,
158        }
159    }
160}