use crate::prelude::*;
#[derive(Debug,Copy,Clone)]
pub enum LinkEnd { Server, Client }
#[derive(Debug,Clone,Hash,Eq,PartialEq,Ord,PartialOrd)]
pub struct ServerName(pub String);
#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq,Ord,PartialOrd)]
pub struct ClientName(pub IpAddr);
#[derive(Clone,Hash,Eq,PartialEq,Ord,PartialOrd)]
pub struct LinkName {
pub server: ServerName,
pub client: ClientName,
}
impl Debug for LinkName {
#[throws(fmt::Error)]
fn fmt(&self, f: &mut fmt::Formatter) { write!(f, "LinkName({})", self)?; }
}
impl FromStr for ClientName {
type Err = AE;
#[throws(AE)]
fn from_str(s: &str) -> Self {
ClientName(
if let Ok(v4addr) = s.parse::<Ipv4Addr>() {
if s != v4addr.to_string() {
throw!(anyhow!("invalid client name (unusual IPv4 address syntax)"));
}
v4addr.into()
} else if let Ok(v6addr) = s.parse::<Ipv6Addr>() {
if s != v6addr.to_string() {
throw!(anyhow!("invalid client name (non-canonical IPv6 address)"));
}
v6addr.into()
} else {
throw!(anyhow!("invalid client name (IPv4 or IPv6 address)"))
}
)
}
}
impl FromStr for ServerName {
type Err = AE;
#[throws(AE)]
fn from_str(s: &str) -> Self {
if ! regex_is_match!(r"
^ (?: SERVER
| [0-9a-z][-0-9a-z]* (:? \.
[0-9a-z][-0-9a-z]* )*
) $"x, s) {
throw!(anyhow!("bad syntax for server name"));
}
if ! regex_is_match!(r"[A-Za-z-]", s) {
throw!(anyhow!("bad syntax for server name \
(too much like an IPv4 address)"));
}
ServerName(s.into())
}
}
impl Display for ServerName {
#[throws(fmt::Error)]
fn fmt(&self, f: &mut fmt::Formatter) { Display::fmt(&self.0, f)?; }
}
impl Display for ClientName {
#[throws(fmt::Error)]
fn fmt(&self, f: &mut fmt::Formatter) { Display::fmt(&self.0, f)?; }
}
impl Display for LinkName {
#[throws(fmt::Error)]
fn fmt(&self, f: &mut fmt::Formatter) {
write!(f, "[{} {}]", &self.server, &self.client)?;
}
}
impl_inspectable_config_value!{ LinkName as Display }