I have the following code snippet and I think it kind of bad style:
let mut ip = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
for iface in (&get_if_addrs::get_if_addrs().unwrap())
.into_iter()
.filter(|&x| x.name == "wlp3s0") {
println!("{:#?}", iface.ip());
ip = iface.ip();
}
let socket = SocketAddr::new(ip, 80);
First I create the variable ip, initialized with a dummy value. Then I use it to create socket. This is rather odd and I would like to create socket only if ip is something. How can this be done in an elegant style?
let ip = get_if_addrs::get_if_addrs().unwrap()
.into_iter()
.find(|x| x.name == "wlp3s0")
.map(|x| x.ip());
Still gives you an Option<IpAddr>.
Or maybe:
let addrs = get_if_addrs::get_if_addrs().unwrap();
if let Some(iface) = addrs.into_iter().find(|x| x.name == "wlp3s0") {
// do something with iface.ip()
}
Oh TIL! Apparently there's also find_map that combines find and map, which sounds great for this, but could think of no way to use that here elegantly, would need a closure that matches x.name and only returns Some(x.ip()) if it matches.
Since the @birkenfeld version returns an Option and the original post optionally replaced a default address, the default can be applied to the option to get the original behaviour with the new code
let ip = get_if_addrs::get_if_addrs().unwrap()
.into_iter()
.find(|x| x.name == "wlp3s0")
.map(|x| x.ip());
.unwrap_or_else(|| IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));
(The unwrap could also be replaced with and_then to make it possible to get the default rather than a panic in case get_if_addrs fails.)