1- use super :: { Ipv4Addr , Ipv6Addr } ;
1+ use super :: { Ipv4Addr , Ipv4AddrMask , Ipv6Addr , Ipv6AddrMask } ;
22use crate :: error:: Error ;
33use crate :: fmt;
44
@@ -121,13 +121,12 @@ impl Ipv4AddrPrefix {
121121
122122 // Private constructor that assumes len <= 32.
123123 // Useful because `Result::unwrap` is not yet usable in const contexts, so `new` can't be used.
124+ #[ unstable( feature = "ip_prefix" , issue = "86991" ) ]
124125 pub ( crate ) const fn new_unchecked ( address : Ipv4Addr , len : u32 ) -> Ipv4AddrPrefix {
125- let masked = {
126- let mask = Ipv4AddrPrefix :: mask ( len) ;
127- u32:: from_be_bytes ( address. octets ( ) ) & mask
128- } ;
126+ let mask = Ipv4AddrMask :: from_prefix ( len) ;
127+ let masked = address. mask ( mask) ;
129128
130- Ipv4AddrPrefix { address_raw : masked, len : len as u8 }
129+ Ipv4AddrPrefix { address_raw : u32 :: from_be_bytes ( masked. octets ( ) ) , len : len as u8 }
131130 }
132131
133132 /// Returns the address specifying this address prefix.
@@ -176,15 +175,18 @@ impl Ipv4AddrPrefix {
176175 self . len as u32
177176 }
178177
179- // Compute the bitmask specified by a prefix length.
180- #[ inline]
181- const fn mask ( len : u32 ) -> u32 {
182- if len == 0 {
183- 0
184- } else {
185- // shift will not overflow as len > 0, so u32::BITS - len < 32
186- u32:: MAX << ( u32:: BITS - len)
187- }
178+ // `192.0.2.0/24` -> `255.255.255.0`
179+ #[ allow( missing_docs) ]
180+ #[ unstable( feature = "ip_mask" , issue = "none" ) ]
181+ pub const fn prefix_mask ( & self ) -> Ipv4AddrMask {
182+ Ipv4AddrMask :: from_prefix ( self . len as u32 )
183+ }
184+
185+ // `192.0.2.0/24` -> `0.0.0.255`
186+ #[ allow( missing_docs) ]
187+ #[ unstable( feature = "ip_mask" , issue = "none" ) ]
188+ pub const fn suffix_mask ( & self ) -> Ipv4AddrMask {
189+ Ipv4AddrMask :: from_suffix ( self . len as u32 )
188190 }
189191
190192 /// Returns `true` if the given address is contained in the network described by this prefix,
@@ -205,8 +207,10 @@ impl Ipv4AddrPrefix {
205207 #[ unstable( feature = "ip_prefix" , issue = "86991" ) ]
206208 #[ inline]
207209 pub const fn contains ( & self , address : & Ipv4Addr ) -> bool {
208- let mask = Ipv4AddrPrefix :: mask ( self . len as u32 ) ;
209- u32:: from_be_bytes ( address. octets ( ) ) & mask == self . address_raw
210+ let mask = self . prefix_mask ( ) ;
211+ let masked = address. mask ( mask) ;
212+
213+ u32:: from_be_bytes ( masked. octets ( ) ) == self . address_raw
210214 }
211215}
212216
@@ -259,13 +263,12 @@ impl Ipv6AddrPrefix {
259263
260264 // Private constructor that assumes len <= 128.
261265 // Useful because `Result::unwrap` is not yet usable in const contexts, so `new` can't be used.
266+ #[ unstable( feature = "ip_prefix" , issue = "86991" ) ]
262267 pub ( crate ) const fn new_unchecked ( address : Ipv6Addr , len : u32 ) -> Ipv6AddrPrefix {
263- let masked = {
264- let mask = Ipv6AddrPrefix :: mask ( len) ;
265- u128:: from_be_bytes ( address. octets ( ) ) & mask
266- } ;
268+ let mask = Ipv6AddrMask :: from_prefix ( len) ;
269+ let masked = address. mask ( mask) ;
267270
268- Ipv6AddrPrefix { address_raw : masked, len : len as u8 }
271+ Ipv6AddrPrefix { address_raw : u128 :: from_be_bytes ( masked. octets ( ) ) , len : len as u8 }
269272 }
270273
271274 /// Returns the address specifying this address prefix.
@@ -313,14 +316,18 @@ impl Ipv6AddrPrefix {
313316 self . len as u32
314317 }
315318
316- // Compute the bitmask specified by a prefix length.
317- const fn mask ( len : u32 ) -> u128 {
318- if len == 0 {
319- 0
320- } else {
321- // shift will not overflow as len > 0, so u128::BITS - len < 128
322- u128:: MAX << ( u128:: BITS - len)
323- }
319+ // `2001:db8::/32` -> `ffff:ffff::`
320+ #[ allow( missing_docs) ]
321+ #[ unstable( feature = "ip_mask" , issue = "none" ) ]
322+ pub const fn prefix_mask ( & self ) -> Ipv6AddrMask {
323+ Ipv6AddrMask :: from_prefix ( self . len as u32 )
324+ }
325+
326+ // `2001:db8::/32` -> `0:0:ffff:ffff::ffff:ffff:ffff:ffff`
327+ #[ allow( missing_docs) ]
328+ #[ unstable( feature = "ip_mask" , issue = "none" ) ]
329+ pub const fn suffix_mask ( & self ) -> Ipv6AddrMask {
330+ Ipv6AddrMask :: from_suffix ( self . len as u32 )
324331 }
325332
326333 /// Returns `true` if the given address is contained in the network described by this prefix,
@@ -341,8 +348,10 @@ impl Ipv6AddrPrefix {
341348 #[ unstable( feature = "ip_prefix" , issue = "86991" ) ]
342349 #[ inline]
343350 pub const fn contains ( & self , address : & Ipv6Addr ) -> bool {
344- let mask = Ipv6AddrPrefix :: mask ( self . len as u32 ) ;
345- u128:: from_be_bytes ( address. octets ( ) ) & mask == self . address_raw
351+ let mask = self . prefix_mask ( ) ;
352+ let masked = address. mask ( mask) ;
353+
354+ u128:: from_be_bytes ( masked. octets ( ) ) == self . address_raw
346355 }
347356}
348357
0 commit comments