浏览代码

wire: move prefix_len impl down to v4 and v6 addrs.

Dario Nieuwenhuis 6 月之前
父节点
当前提交
23be2beab3
共有 3 个文件被更改,包括 57 次插入20 次删除
  1. 5 20
      src/wire/ip.rs
  2. 26 0
      src/wire/ipv4.rs
  3. 26 0
      src/wire/ipv6.rs

+ 5 - 20
src/wire/ip.rs

@@ -180,27 +180,12 @@ impl Address {
     /// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`,
     /// where `prefix_len` is the number of leading zeroes. Return `None` otherwise.
     pub fn prefix_len(&self) -> Option<u8> {
-        let mut ones = true;
-        let mut prefix_len = 0;
-        for byte in self.as_bytes() {
-            let mut mask = 0x80;
-            for _ in 0..8 {
-                let one = *byte & mask != 0;
-                if ones {
-                    // Expect 1s until first 0
-                    if one {
-                        prefix_len += 1;
-                    } else {
-                        ones = false;
-                    }
-                } else if one {
-                    // 1 where 0 was expected
-                    return None;
-                }
-                mask >>= 1;
-            }
+        match self {
+            #[cfg(feature = "proto-ipv4")]
+            Address::Ipv4(addr) => addr.prefix_len(),
+            #[cfg(feature = "proto-ipv6")]
+            Address::Ipv6(addr) => addr.prefix_len(),
         }
-        Some(prefix_len)
     }
 }
 

+ 26 - 0
src/wire/ipv4.rs

@@ -108,6 +108,32 @@ impl Address {
     pub const fn into_address(self) -> super::IpAddress {
         super::IpAddress::Ipv4(self)
     }
+
+    /// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`,
+    /// where `prefix_len` is the number of leading zeroes. Return `None` otherwise.
+    pub fn prefix_len(&self) -> Option<u8> {
+        let mut ones = true;
+        let mut prefix_len = 0;
+        for byte in self.as_bytes() {
+            let mut mask = 0x80;
+            for _ in 0..8 {
+                let one = *byte & mask != 0;
+                if ones {
+                    // Expect 1s until first 0
+                    if one {
+                        prefix_len += 1;
+                    } else {
+                        ones = false;
+                    }
+                } else if one {
+                    // 1 where 0 was expected
+                    return None;
+                }
+                mask >>= 1;
+            }
+        }
+        Some(prefix_len)
+    }
 }
 
 impl From<::core::net::Ipv4Addr> for Address {

+ 26 - 0
src/wire/ipv6.rs

@@ -310,6 +310,32 @@ impl Address {
     pub const fn into_address(self) -> super::IpAddress {
         super::IpAddress::Ipv6(self)
     }
+
+    /// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`,
+    /// where `prefix_len` is the number of leading zeroes. Return `None` otherwise.
+    pub fn prefix_len(&self) -> Option<u8> {
+        let mut ones = true;
+        let mut prefix_len = 0;
+        for byte in self.as_bytes() {
+            let mut mask = 0x80;
+            for _ in 0..8 {
+                let one = *byte & mask != 0;
+                if ones {
+                    // Expect 1s until first 0
+                    if one {
+                        prefix_len += 1;
+                    } else {
+                        ones = false;
+                    }
+                } else if one {
+                    // 1 where 0 was expected
+                    return None;
+                }
+                mask >>= 1;
+            }
+        }
+        Some(prefix_len)
+    }
 }
 
 impl From<::core::net::Ipv6Addr> for Address {