use std::borrow::Cow; use std::str::FromStr; use serde::{Deserialize, Serialize}; use crate::common::StringValue; pub mod check; pub use check::ContactCheck; pub mod create; pub use create::ContactCreate; pub mod delete; pub use delete::ContactDelete; pub mod info; pub use info::ContactInfo; pub mod update; pub use update::ContactUpdate; pub const XMLNS: &str = "urn:ietf:params:xml:ns:contact-1.0"; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Country(celes::Country); impl FromStr for Country { type Err = ::Err; fn from_str(s: &str) -> Result { Ok(Self(celes::Country::from_str(s)?)) } } impl std::ops::Deref for Country { type Target = celes::Country; fn deref(&self) -> &Self::Target { &self.0 } } /// The <authInfo> tag for domain and contact transactions #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ContactAuthInfo<'a> { /// The <pw> tag under <authInfo> #[serde(rename = "contact:pw", alias = "pw")] pub password: StringValue<'a>, } impl<'a> ContactAuthInfo<'a> { /// Creates a ContactAuthInfo instance with the given password pub fn new(password: &'a str) -> Self { Self { password: password.into(), } } } /// The data for <voice> and <fax> types on domain transactions #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Phone<'a> { /// The inner text on the <voice> and <fax> tags #[serde(rename = "$value")] pub number: Cow<'a, str>, /// The value of the 'x' attr on <voice> and <fax> tags #[serde(rename = "x")] pub extension: Option>, } impl<'a> Phone<'a> { /// Creates a new Phone instance with a given phone number pub fn new(number: &'a str) -> Self { Self { extension: None, number: number.into(), } } /// Sets the extension value of the Phone type pub fn set_extension(&mut self, ext: &'a str) { self.extension = Some(ext.into()); } } /// The <addr> type on contact transactions #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Address<'a> { /// The <street> tags under <addr> #[serde(rename = "contact:street", alias = "street")] pub street: Vec>, /// The <city> tag under <addr> #[serde(rename = "contact:city", alias = "city")] pub city: StringValue<'a>, /// The <sp> tag under <addr> #[serde(rename = "contact:sp", alias = "sp")] pub province: StringValue<'a>, /// The <pc> tag under <addr> #[serde(rename = "contact:pc", alias = "pc")] pub postal_code: StringValue<'a>, /// The <cc> tag under <addr> #[serde(rename = "contact:cc", alias = "cc")] pub country: Country, } impl<'a> Address<'a> { /// Creates a new Address instance pub fn new( street: &[&'a str], city: &'a str, province: &'a str, postal_code: &'a str, country: Country, ) -> Self { let street = street.iter().map(|&s| s.into()).collect(); Self { street, city: city.into(), province: province.into(), postal_code: postal_code.into(), country, } } } /// The <postalInfo> type on contact transactions #[derive(Serialize, Deserialize, Debug, Clone)] pub struct PostalInfo<'a> { /// The 'type' attr on <postalInfo> #[serde(rename = "type")] pub info_type: String, /// The <name> tag under <postalInfo> #[serde(rename = "contact:name", alias = "name")] pub name: StringValue<'a>, /// The <org> tag under <postalInfo> #[serde(rename = "contact:org", alias = "org")] pub organization: StringValue<'a>, /// The <addr> tag under <postalInfo> #[serde(rename = "contact:addr", alias = "addr")] pub address: Address<'a>, } impl<'a> PostalInfo<'a> { /// Creates a new PostalInfo instance pub fn new( info_type: &str, name: &'a str, organization: &'a str, address: Address<'a>, ) -> Self { Self { info_type: info_type.to_string(), name: name.into(), organization: organization.into(), address, } } }