1 // Copyright 2021 Ian Jackson and contributors to Hippotat
2 // SPDX-License-Identifier: GPL-3.0-or-later
3 // There is NO WARRANTY.
7 #[derive(Debug,Copy,Clone)]
8 pub enum LinkEnd { Server, Client }
10 #[derive(Debug,Clone,Hash,Eq,PartialEq,Ord,PartialOrd)]
11 pub struct ServerName(pub String);
13 #[derive(Debug,Clone,Copy,Hash,Eq,PartialEq,Ord,PartialOrd)]
14 pub struct ClientName(pub IpAddr);
16 #[derive(Debug,Clone,Hash,Eq,PartialEq,Ord,PartialOrd)]
18 pub server: ServerName,
19 pub client: ClientName,
22 impl FromStr for ClientName {
25 fn from_str(s: &str) -> Self {
27 if let Ok(v4addr) = s.parse::<Ipv4Addr>() {
28 if s != v4addr.to_string() {
29 throw!(anyhow!("invalid client name (unusual IPv4 address syntax)"));
32 } else if let Ok(v6addr) = s.parse::<Ipv6Addr>() {
33 if s != v6addr.to_string() {
34 throw!(anyhow!("invalid client name (non-canonical IPv6 address)"));
38 throw!(anyhow!("invalid client name (IPv4 or IPv6 address)"))
44 impl FromStr for ServerName {
47 fn from_str(s: &str) -> Self {
48 if ! regex_is_match!(r"
50 | [0-9a-z][-0-9a-z]* (:? \.
53 throw!(anyhow!("bad syntax for server name"));
55 if ! regex_is_match!(r"[A-Za-z-]", s) {
56 throw!(anyhow!("bad syntax for server name \
57 (too much like an IPv4 address)"));
63 impl Display for ServerName {
65 fn fmt(&self, f: &mut fmt::Formatter) { Display::fmt(&self.0, f)?; }
67 impl Display for ClientName {
69 fn fmt(&self, f: &mut fmt::Formatter) { Display::fmt(&self.0, f)?; }
71 impl Display for LinkName {
73 fn fmt(&self, f: &mut fmt::Formatter) {
74 write!(f, "[{} {}]", &self.server, &self.client)?;