In Rust, it is easy to create an IpAddr
from an IpV4Addr
:
let ipv4 = IpV4Addr::new(127,0,0,1);
let ip = IpAddr::V4(ipv4);
But it seems that there is no way back:
if ip.is_ipv4() {
let ipv4: IpV4Addr = .....?
}
The reason is that I need to access the octets of the IPv4 address at some point (via IPv4::octets
) to transfer them over the network. However, I'd like to use the more generic IpAddr
representation in other parts of the application, since I want to implement IPv6 in the future, therefore making the network code not IPv4-specific.
IpAddr
is an abstraction for IP addresses. It is an enum which holds either an Ipv4Addr
or Ipv6Addr
and some methods to provide abstract access to either.
Rust won't let you cast an IpAddr
to an Ipv4Addr
because what if it's actually an Ipv6Addr
? You have to handle that case as well. You convince Rust that you've handled all possibilities with match
.
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
fn main() {
let ips = [
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
];
for ip in ips.iter() {
match *ip {
IpAddr::V4(ip4) => println!("ipv4: {}, octets: {:?}", ip4, ip4.octets()),
IpAddr::V6(ip6) => println!("ipv6: {}, segments: {:?}", ip6, ip6.segments()),
}
}
}
There is no need for a default case because the Rust type checker knows there is no other possibility. ips
is an array of IpAddr
and that contains only two possibilities, V4 or V6. In fact, Rust will warn if you put one there so should IpAddr
change in the future you will be made aware with a compile error.
IpAddr
is an enum, so you can use pattern matching:
if let IpAddr::V4(ipv4) = ip {
// here ipv4 is of type IpV4Addr
}
// or, if you need to handle IPv6 as well
match ip {
IpAddr::V4(ipv4) => { /* handle IPv4 */ }
IpAddr::V6(ipv6) => { /* handle IPv6 */ }
}
Also, IpAddr
is Copy
, so you don't even need to worry about consuming its original value (the ip
variable), it will just be implicitly copied for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With