File: types.rs

package info (click to toggle)
hippotat 1.2.3
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 684 kB
  • sloc: sh: 423; makefile: 130; perl: 84; python: 79; ansic: 34
file content (83 lines) | stat: -rw-r--r-- 2,300 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright 2021-2022 Ian Jackson and contributors to Hippotat
// SPDX-License-Identifier: GPL-3.0-or-later WITH LicenseRef-Hippotat-OpenSSL-Exception
// There is NO WARRANTY.

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 }