Coverage Report

Created: 2025-11-11 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ipnet-2.11.0/src/mask.rs
Line
Count
Source
1
use crate::PrefixLenError;
2
#[cfg(not(feature = "std"))]
3
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
4
#[cfg(feature = "std")]
5
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
6
7
/// Converts a `IpAddr` network mask into a prefix.
8
///
9
/// # Errors
10
/// If the mask is invalid this will return an `PrefixLenError`.
11
0
pub fn ip_mask_to_prefix(mask: IpAddr) -> Result<u8, PrefixLenError> {
12
0
    match mask {
13
0
        IpAddr::V4(mask) => ipv4_mask_to_prefix(mask),
14
0
        IpAddr::V6(mask) => ipv6_mask_to_prefix(mask),
15
    }
16
0
}
17
18
/// Converts a `Ipv4Addr` network mask into a prefix.
19
///
20
/// # Errors
21
/// If the mask is invalid this will return an `PrefixLenError`.
22
0
pub fn ipv4_mask_to_prefix(mask: Ipv4Addr) -> Result<u8, PrefixLenError> {
23
0
    let mask = u32::from(mask);
24
25
0
    let prefix = mask.leading_ones();
26
0
    if mask.checked_shl(prefix).unwrap_or(0) == 0 {
27
0
        Ok(prefix as u8)
28
    } else {
29
0
        Err(PrefixLenError)
30
    }
31
0
}
32
33
/// Converts a `Ipv6Addr` network mask into a prefix.
34
///
35
/// # Errors
36
/// If the mask is invalid this will return an `PrefixLenError`.
37
0
pub fn ipv6_mask_to_prefix(mask: Ipv6Addr) -> Result<u8, PrefixLenError> {
38
0
    let mask = u128::from(mask);
39
40
0
    let prefix = mask.leading_ones();
41
0
    if mask.checked_shl(prefix).unwrap_or(0) == 0 {
42
0
        Ok(prefix as u8)
43
    } else {
44
0
        Err(PrefixLenError)
45
    }
46
0
}
47
48
#[cfg(test)]
49
mod tests {
50
    use super::*;
51
    use crate::{Ipv4Net, Ipv6Net};
52
53
    #[test]
54
    fn v4_mask_to_prefix() {
55
        let mask = Ipv4Addr::new(255, 255, 255, 128);
56
        let prefix = ipv4_mask_to_prefix(mask);
57
        assert_eq!(prefix, Ok(25));
58
    }
59
60
    #[test]
61
    fn v4_mask_to_prefix_max() {
62
        let mask = Ipv4Addr::from(u32::MAX);
63
        let prefix = ipv4_mask_to_prefix(mask);
64
        assert_eq!(prefix, Ok(32));
65
    }
66
67
    #[test]
68
    fn invalid_v4_mask_to_prefix() {
69
        let mask = Ipv4Addr::new(255, 0, 255, 0);
70
        let prefix = ipv4_mask_to_prefix(mask);
71
        assert!(prefix.is_err());
72
    }
73
74
    #[test]
75
    fn ipv4net_with_netmask() {
76
        {
77
            // Positive test-case.
78
            let addr = Ipv4Addr::new(127, 0, 0, 1);
79
            let mask = Ipv4Addr::new(255, 0, 0, 0);
80
            let net = Ipv4Net::with_netmask(addr, mask).unwrap();
81
            let expected = Ipv4Net::new(Ipv4Addr::new(127, 0, 0, 1), 8).unwrap();
82
            assert_eq!(net, expected);
83
        }
84
        {
85
            // Negative test-case.
86
            let addr = Ipv4Addr::new(127, 0, 0, 1);
87
            let mask = Ipv4Addr::new(255, 0, 255, 0);
88
            Ipv4Net::with_netmask(addr, mask).unwrap_err();
89
        }
90
    }
91
92
    #[test]
93
    fn v6_mask_to_prefix() {
94
        let mask = Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0);
95
        let prefix = ipv6_mask_to_prefix(mask);
96
        assert_eq!(prefix, Ok(48));
97
    }
98
99
    #[test]
100
    fn v6_mask_to_prefix_max() {
101
        let mask = Ipv6Addr::from(u128::MAX);
102
        let prefix = ipv6_mask_to_prefix(mask);
103
        assert_eq!(prefix, Ok(128));
104
    }
105
106
    #[test]
107
    fn invalid_v6_mask_to_prefix() {
108
        let mask = Ipv6Addr::new(0, 0, 0xffff, 0xffff, 0, 0, 0, 0);
109
        let prefix = ipv6_mask_to_prefix(mask);
110
        assert!(prefix.is_err());
111
    }
112
113
    #[test]
114
    fn ipv6net_with_netmask() {
115
        {
116
            // Positive test-case.
117
            let addr = Ipv6Addr::new(0xff01, 0, 0, 0x17, 0, 0, 0, 0x2);
118
            let mask = Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0);
119
            let net = Ipv6Net::with_netmask(addr, mask).unwrap();
120
            let expected =
121
                Ipv6Net::new(Ipv6Addr::new(0xff01, 0, 0, 0x17, 0, 0, 0, 0x2), 48).unwrap();
122
            assert_eq!(net, expected);
123
        }
124
        {
125
            // Negative test-case.
126
            let addr = Ipv6Addr::new(0xff01, 0, 0, 0x17, 0, 0, 0, 0x2);
127
            let mask = Ipv6Addr::new(0, 0, 0xffff, 0xffff, 0, 0, 0, 0);
128
            Ipv6Net::with_netmask(addr, mask).unwrap_err();
129
        }
130
    }
131
}