validify/validation/
ip.rs

1use std::net::IpAddr;
2use std::str::FromStr;
3
4/// Validates whether the given string is an IP V4
5#[must_use]
6pub fn validate_ip_v4<T>(val: T) -> bool
7where
8    T: AsRef<str>,
9{
10    IpAddr::from_str(val.as_ref()).map_or(false, |i| i.is_ipv4())
11}
12
13/// Validates whether the given string is an IP V6
14#[must_use]
15pub fn validate_ip_v6<T>(val: T) -> bool
16where
17    T: AsRef<str>,
18{
19    IpAddr::from_str(val.as_ref()).map_or(false, |i| i.is_ipv6())
20}
21
22/// Validates whether the given string is an IP
23#[must_use]
24pub fn validate_ip<T>(val: T) -> bool
25where
26    T: AsRef<str>,
27{
28    IpAddr::from_str(val.as_ref()).is_ok()
29}
30
31#[cfg(test)]
32mod tests {
33
34    use super::{validate_ip, validate_ip_v4, validate_ip_v6};
35
36    #[test]
37    fn test_validate_ip() {
38        let tests = vec![
39            ("1.1.1.1", true),
40            ("255.0.0.0", true),
41            ("0.0.0.0", true),
42            ("256.1.1.1", false),
43            ("25.1.1.", false),
44            ("25,1,1,1", false),
45            ("fe80::223:6cff:fe8a:2e8a", true),
46            ("::ffff:254.42.16.14", true),
47            ("2a02::223:6cff :fe8a:2e8a", false),
48        ];
49
50        for (input, expected) in tests {
51            assert_eq!(validate_ip(input), expected);
52        }
53    }
54
55    #[test]
56    fn test_validate_ip_cow() {
57        let test = "1.1.1.1";
58        assert!(validate_ip(test));
59        let test = String::from("1.1.1.1");
60        assert!(validate_ip(test.as_str()));
61        let test = "2a02::223:6cff :fe8a:2e8a";
62        assert!(!validate_ip(test));
63        let test = String::from("2a02::223:6cff :fe8a:2e8a");
64        assert!(!validate_ip(test.as_str()));
65    }
66
67    #[test]
68    fn test_validate_ip_v4() {
69        let tests = vec![
70            ("1.1.1.1", true),
71            ("255.0.0.0", true),
72            ("0.0.0.0", true),
73            ("256.1.1.1", false),
74            ("25.1.1.", false),
75            ("25,1,1,1", false),
76            ("25.1 .1.1", false),
77            ("1.1.1.1\n", false),
78            ("٧.2٥.3٣.243", false),
79        ];
80
81        for (input, expected) in tests {
82            assert_eq!(validate_ip_v4(input), expected);
83        }
84    }
85
86    #[test]
87    fn test_validate_ip_v4_cow() {
88        let test = "1.1.1.1";
89        assert!(validate_ip_v4(test));
90        let test = String::from("1.1.1.1");
91        assert!(validate_ip_v4(test.as_str()));
92        let test = "٧.2٥.3٣.243";
93        assert!(!validate_ip_v4(test));
94        let test = String::from("٧.2٥.3٣.243");
95        assert!(!validate_ip_v4(test.as_str()));
96    }
97
98    #[test]
99    fn test_validate_ip_v6() {
100        let tests = vec![
101            ("fe80::223:6cff:fe8a:2e8a", true),
102            ("2a02::223:6cff:fe8a:2e8a", true),
103            ("1::2:3:4:5:6:7", true),
104            ("::", true),
105            ("::a", true),
106            ("2::", true),
107            ("::ffff:254.42.16.14", true),
108            ("::ffff:0a0a:0a0a", true),
109            ("::254.42.16.14", true),
110            ("::0a0a:0a0a", true),
111            ("foo", false),
112            ("127.0.0.1", false),
113            ("12345::", false),
114            ("1::2::3::4", false),
115            ("1::zzz", false),
116            ("1:2", false),
117            ("fe80::223: 6cff:fe8a:2e8a", false),
118            ("2a02::223:6cff :fe8a:2e8a", false),
119            ("::ffff:999.42.16.14", false),
120            ("::ffff:zzzz:0a0a", false),
121        ];
122
123        for (input, expected) in tests {
124            assert_eq!(validate_ip_v6(input), expected);
125        }
126    }
127
128    #[test]
129    fn test_validate_ip_v6_cow() {
130        let test = "fe80::223:6cff:fe8a:2e8a";
131        assert!(validate_ip_v6(test));
132        let test = String::from("fe80::223:6cff:fe8a:2e8a");
133        assert!(validate_ip_v6(test.as_str()));
134        let test = "::ffff:zzzz:0a0a";
135        assert!(!validate_ip_v6(test));
136        let test = String::from("::ffff:zzzz:0a0a");
137        assert!(!validate_ip_v6(test.as_str()));
138    }
139}