1 #[cfg(test)]
2 mod network_type_test;
3
4 use crate::error::*;
5
6 use serde::{Deserialize, Serialize};
7 use std::fmt;
8 use std::net::IpAddr;
9
10 pub(crate) const UDP: &str = "udp";
11 pub(crate) const TCP: &str = "tcp";
12
13 #[must_use]
supported_network_types() -> Vec<NetworkType>14 pub fn supported_network_types() -> Vec<NetworkType> {
15 vec![
16 NetworkType::Udp4,
17 NetworkType::Udp6,
18 //NetworkType::TCP4,
19 //NetworkType::TCP6,
20 ]
21 }
22
23 /// Represents the type of network.
24 #[derive(PartialEq, Debug, Copy, Clone, Eq, Hash, Serialize, Deserialize)]
25 pub enum NetworkType {
26 #[serde(rename = "unspecified")]
27 Unspecified,
28
29 /// Indicates UDP over IPv4.
30 #[serde(rename = "udp4")]
31 Udp4,
32
33 /// Indicates UDP over IPv6.
34 #[serde(rename = "udp6")]
35 Udp6,
36
37 /// Indicates TCP over IPv4.
38 #[serde(rename = "tcp4")]
39 Tcp4,
40
41 /// Indicates TCP over IPv6.
42 #[serde(rename = "tcp6")]
43 Tcp6,
44 }
45
46 impl From<u8> for NetworkType {
from(v: u8) -> Self47 fn from(v: u8) -> Self {
48 match v {
49 1 => Self::Udp4,
50 2 => Self::Udp6,
51 3 => Self::Tcp4,
52 4 => Self::Tcp6,
53 _ => Self::Unspecified,
54 }
55 }
56 }
57
58 impl fmt::Display for NetworkType {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 let s = match *self {
61 Self::Udp4 => "udp4",
62 Self::Udp6 => "udp6",
63 Self::Tcp4 => "tcp4",
64 Self::Tcp6 => "tcp6",
65 Self::Unspecified => "unspecified",
66 };
67 write!(f, "{s}")
68 }
69 }
70
71 impl Default for NetworkType {
default() -> Self72 fn default() -> Self {
73 Self::Unspecified
74 }
75 }
76
77 impl NetworkType {
78 /// Returns true when network is UDP4 or UDP6.
79 #[must_use]
is_udp(self) -> bool80 pub fn is_udp(self) -> bool {
81 self == Self::Udp4 || self == Self::Udp6
82 }
83
84 /// Returns true when network is TCP4 or TCP6.
85 #[must_use]
is_tcp(self) -> bool86 pub fn is_tcp(self) -> bool {
87 self == Self::Tcp4 || self == Self::Tcp6
88 }
89
90 /// Returns the short network description.
91 #[must_use]
network_short(self) -> String92 pub fn network_short(self) -> String {
93 match self {
94 Self::Udp4 | Self::Udp6 => UDP.to_owned(),
95 Self::Tcp4 | Self::Tcp6 => TCP.to_owned(),
96 Self::Unspecified => "Unspecified".to_owned(),
97 }
98 }
99
100 /// Returns true if the network is reliable.
101 #[must_use]
is_reliable(self) -> bool102 pub const fn is_reliable(self) -> bool {
103 match self {
104 Self::Tcp4 | Self::Tcp6 => true,
105 Self::Udp4 | Self::Udp6 | Self::Unspecified => false,
106 }
107 }
108
109 /// Returns whether the network type is IPv4 or not.
110 #[must_use]
is_ipv4(self) -> bool111 pub const fn is_ipv4(self) -> bool {
112 match self {
113 Self::Udp4 | Self::Tcp4 => true,
114 Self::Udp6 | Self::Tcp6 | Self::Unspecified => false,
115 }
116 }
117
118 /// Returns whether the network type is IPv6 or not.
119 #[must_use]
is_ipv6(self) -> bool120 pub const fn is_ipv6(self) -> bool {
121 match self {
122 Self::Udp6 | Self::Tcp6 => true,
123 Self::Udp4 | Self::Tcp4 | Self::Unspecified => false,
124 }
125 }
126 }
127
128 /// Determines the type of network based on the short network string and an IP address.
determine_network_type(network: &str, ip: &IpAddr) -> Result<NetworkType>129 pub(crate) fn determine_network_type(network: &str, ip: &IpAddr) -> Result<NetworkType> {
130 let ipv4 = ip.is_ipv4();
131 let net = network.to_lowercase();
132 if net.starts_with(UDP) {
133 if ipv4 {
134 Ok(NetworkType::Udp4)
135 } else {
136 Ok(NetworkType::Udp6)
137 }
138 } else if net.starts_with(TCP) {
139 if ipv4 {
140 Ok(NetworkType::Tcp4)
141 } else {
142 Ok(NetworkType::Tcp6)
143 }
144 } else {
145 Err(Error::ErrDetermineNetworkType)
146 }
147 }
148