libsubconverter/utils/
network.rs1use std::net::{IpAddr, ToSocketAddrs};
4
5pub fn hostname_to_ip_addr(host: &str) -> Option<String> {
15 let sock_addr = format!("{}:0", host).to_socket_addrs();
17
18 match sock_addr {
19 Ok(mut addrs) => {
20 while let Some(addr) = addrs.next() {
22 match addr.ip() {
23 IpAddr::V4(ipv4) => return Some(ipv4.to_string()),
24 IpAddr::V6(ipv6) => return Some(ipv6.to_string()),
25 }
26 }
27 None
28 }
29 Err(_) => None,
30 }
31}
32
33pub fn is_ipv4(s: &str) -> bool {
43 let parts: Vec<&str> = s.split('.').collect();
44
45 if parts.len() != 4 {
46 return false;
47 }
48
49 for part in parts {
50 match part.parse::<u8>() {
52 Ok(_) => continue,
53 Err(_) => return false,
54 }
55 }
56
57 true
58}
59
60pub fn is_ipv6(s: &str) -> bool {
70 s.contains(':')
73}
74
75pub fn is_link(link: &str) -> bool {
77 link.starts_with("http://")
78 || link.starts_with("https://")
79 || link.starts_with("data:")
80 || link.starts_with("content://")
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn test_is_ipv4_valid() {
89 assert!(is_ipv4("192.168.1.1"));
90 assert!(is_ipv4("127.0.0.1"));
91 assert!(is_ipv4("8.8.8.8"));
92 assert!(is_ipv4("255.255.255.255"));
93 }
94
95 #[test]
96 fn test_is_ipv4_invalid() {
97 assert!(!is_ipv4("192.168.1"));
98 assert!(!is_ipv4("192.168.1.256"));
99 assert!(!is_ipv4("192.168.1.a"));
100 assert!(!is_ipv4("192.168.1.1.1"));
101 assert!(!is_ipv4("2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
102 }
103
104 #[test]
105 fn test_is_ipv6_valid() {
106 assert!(is_ipv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
107 assert!(is_ipv6("::1"));
108 assert!(is_ipv6("2001:db8::"));
109 }
110
111 #[test]
112 fn test_is_ipv6_invalid() {
113 assert!(!is_ipv6("192.168.1.1"));
114 assert!(!is_ipv6("not an ip"));
115 }
116
117 #[test]
118 fn test_hostname_to_ip_addr() {
119 let ip = hostname_to_ip_addr("localhost");
121 assert!(ip.is_some());
122 assert!(ip.as_ref().unwrap() == "127.0.0.1" || ip.as_ref().unwrap() == "::1");
123 }
124}