Skip to content

Commit 23be2be

Browse files
committed
wire: move prefix_len impl down to v4 and v6 addrs.
1 parent 11b6385 commit 23be2be

File tree

3 files changed

+57
-20
lines changed

3 files changed

+57
-20
lines changed

src/wire/ip.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -180,27 +180,12 @@ impl Address {
180180
/// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`,
181181
/// where `prefix_len` is the number of leading zeroes. Return `None` otherwise.
182182
pub fn prefix_len(&self) -> Option<u8> {
183-
let mut ones = true;
184-
let mut prefix_len = 0;
185-
for byte in self.as_bytes() {
186-
let mut mask = 0x80;
187-
for _ in 0..8 {
188-
let one = *byte & mask != 0;
189-
if ones {
190-
// Expect 1s until first 0
191-
if one {
192-
prefix_len += 1;
193-
} else {
194-
ones = false;
195-
}
196-
} else if one {
197-
// 1 where 0 was expected
198-
return None;
199-
}
200-
mask >>= 1;
201-
}
183+
match self {
184+
#[cfg(feature = "proto-ipv4")]
185+
Address::Ipv4(addr) => addr.prefix_len(),
186+
#[cfg(feature = "proto-ipv6")]
187+
Address::Ipv6(addr) => addr.prefix_len(),
202188
}
203-
Some(prefix_len)
204189
}
205190
}
206191

src/wire/ipv4.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,32 @@ impl Address {
108108
pub const fn into_address(self) -> super::IpAddress {
109109
super::IpAddress::Ipv4(self)
110110
}
111+
112+
/// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`,
113+
/// where `prefix_len` is the number of leading zeroes. Return `None` otherwise.
114+
pub fn prefix_len(&self) -> Option<u8> {
115+
let mut ones = true;
116+
let mut prefix_len = 0;
117+
for byte in self.as_bytes() {
118+
let mut mask = 0x80;
119+
for _ in 0..8 {
120+
let one = *byte & mask != 0;
121+
if ones {
122+
// Expect 1s until first 0
123+
if one {
124+
prefix_len += 1;
125+
} else {
126+
ones = false;
127+
}
128+
} else if one {
129+
// 1 where 0 was expected
130+
return None;
131+
}
132+
mask >>= 1;
133+
}
134+
}
135+
Some(prefix_len)
136+
}
111137
}
112138

113139
impl From<::core::net::Ipv4Addr> for Address {

src/wire/ipv6.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,32 @@ impl Address {
310310
pub const fn into_address(self) -> super::IpAddress {
311311
super::IpAddress::Ipv6(self)
312312
}
313+
314+
/// If `self` is a CIDR-compatible subnet mask, return `Some(prefix_len)`,
315+
/// where `prefix_len` is the number of leading zeroes. Return `None` otherwise.
316+
pub fn prefix_len(&self) -> Option<u8> {
317+
let mut ones = true;
318+
let mut prefix_len = 0;
319+
for byte in self.as_bytes() {
320+
let mut mask = 0x80;
321+
for _ in 0..8 {
322+
let one = *byte & mask != 0;
323+
if ones {
324+
// Expect 1s until first 0
325+
if one {
326+
prefix_len += 1;
327+
} else {
328+
ones = false;
329+
}
330+
} else if one {
331+
// 1 where 0 was expected
332+
return None;
333+
}
334+
mask >>= 1;
335+
}
336+
}
337+
Some(prefix_len)
338+
}
313339
}
314340

315341
impl From<::core::net::Ipv6Addr> for Address {

0 commit comments

Comments
 (0)