pub mod acme; pub mod checker; pub mod config; pub mod manager; use std::fmt; use std::str::FromStr; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use trust_dns_client::rr as trust_dns_rr; #[derive(Debug, Clone)] /// Validated representation of a domain name pub struct Name { inner: trust_dns_rr::Name, utf8_str: String, } impl Name { pub fn as_str(&self) -> &str { self.utf8_str.as_str() } } impl fmt::Display for Name { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.utf8_str) } } impl FromStr for Name { type Err = ::Err; fn from_str(s: &str) -> Result { let mut n = trust_dns_rr::Name::from_str(s)?; let utf8_str = n.clone().to_utf8(); n.set_fqdn(true); Ok(Name { inner: n, utf8_str }) } } impl Serialize for Name { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(self.as_str()) } } struct NameVisitor; impl<'de> de::Visitor<'de> for NameVisitor { type Value = Name; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { write!(formatter, "a valid domain name") } fn visit_str(self, s: &str) -> Result where E: de::Error, { match Name::from_str(s) { Ok(n) => Ok(n), Err(e) => Err(E::custom(format!("invalid domain name: {}", e))), } } } impl<'de> Deserialize<'de> for Name { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_str(NameVisitor) } }