Idiomatic find loop

I'm iterating over USB devices:

let device;
let device_descriptor;
for d in context.devices()?.iter() {
    let dd = d.device_descriptor()?;
    if dd.vendor_id() == find_vendor_id && dd.product_id() == find_product_id {
        device_descriptor = dd;
        device = d.open()?;
        break;
    }
}

If nothing is found I would like to return an error from the surrounding function, so device and device_descriptor are never actually uninitialized, but I don't know how to tell Rust that.

I'd like to avoid moving the loop to a separate function here.

What happens if no device is found? Then these variables are uninitialized. Usually you use Option in this scenario to represent maybe not finding the device. Another option is to use Iterator::find to search for the device.

Then I want to return from main() with an error. But I can't do that, because I can't actually check whether they are still uninitialized.

So, use Option :slight_smile:. Then you can check if they are None and return because the device wasn't found.

let mut device = None;
for d in context.devices()?.iter() {
    let dd = d.device_descriptor()?;
    if dd.vendor_id() == find_vendor_id && dd.product_id() == find_product_id {
        device = Some((dd, d.open()?));
        break;
    }
}
let (device, device_descriptor) = device.ok_or(some_error)?;
1 Like