Advise on Programing style

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?

why not

let ip = (&get_if_addrs::get_if_addrs().unwrap())
    .into_iter()
    .filter(|&x| x.name == "wlp3s0")
    .map(|x| x.ip())
    .next();

this will give an Option<IpAddr::V4>, which will contain the IP address if it matches or None otherwise.

2 Likes

There's a find() method on iterators :slight_smile:

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()
}
6 Likes

Yes, that's what I was looking for

Thanks. The last "two line approach" looks even better for my taste..

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.)

The OP said: "... and I would like to create socket only if ip is something".

Ops, sorry, I missed that part. Then no unwrap_or_else is needed. (It might still be a good idea to replace the first unwrap with an and_then.)