ip2d/
lib.rs

1use std::net::IpAddr::{self, *};
2use std::net::Ipv6Addr;
3
4use anyhow::Result;
5
6pub fn to_integer(ip: &str) -> Result<u128> {
7    let addr: IpAddr = ip.parse()?;
8    match addr {
9        V4(a) => {
10            let res: u32 = a.into();
11            Ok(res as u128)
12        }
13        V6(a) => Ok(a.into()),
14    }
15}
16
17pub fn to_str(num: u128, v6: bool) -> String {
18    let addr = Ipv6Addr::from(num);
19    if v6 {
20        return addr.to_string();
21    }
22    // Try and see if we can return an IPv4 address, otherwise fallback to IPv6.
23    match addr.to_ipv4() {
24        Some(a) => a.to_string(),
25        None => addr.to_string(),
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use super::{to_integer, to_str};
32
33    #[test]
34    fn to_integer_works_with_255_0_255_0() {
35        let result = to_integer("255.0.255.0").unwrap();
36        assert_eq!(result, 4278255360);
37    }
38
39    #[test]
40    fn to_integer_works_with_0_0_0_1() {
41        let result = to_integer("0.0.0.1").unwrap();
42        assert_eq!(result, 1);
43    }
44
45    #[test]
46    fn to_integer_works_with_255_255_255_255() {
47        let result = to_integer("255.255.255.255").unwrap();
48        assert_eq!(result, 0xFFFFFFFF);
49    }
50
51    #[test]
52    fn to_integer_works_with_ipv6() {
53        let cases = vec!["::1", "2001:4860:4860::8888", "2606:4700:4700::1111"];
54        let expected = vec![
55            1,
56            42541956123769884636017138956568135816,
57            50543257694033307102031451402929180945,
58        ];
59        for (i, case) in cases.iter().enumerate() {
60            let result = to_integer(case).unwrap();
61            assert_eq!(result, expected[i]);
62        }
63    }
64
65    #[test]
66    fn to_integer_parse_failure() {
67        let cases = vec!["256.0.0.0", "1::::1"];
68        for case in cases {
69            assert!(to_integer(case).is_err());
70        }
71    }
72
73    #[test]
74    fn str_works_with_ipv6() {
75        let result = to_str(50543257694033307102031451402929180945, false);
76        assert_eq!(result, "2606:4700:4700::1111");
77    }
78
79    #[test]
80    fn str_works_with_4278255360() {
81        let result = to_str(4278255360, false);
82        assert_eq!(result, "255.0.255.0");
83    }
84
85    #[test]
86    fn str_works_with_1() {
87        let result = to_str(1, false);
88        assert_eq!(result, "0.0.0.1");
89    }
90
91    #[test]
92    fn str_works_with_4294967295() {
93        let result = to_str(4294967295, false);
94        assert_eq!(result, "255.255.255.255");
95    }
96}