For loop to iterator with error handling

I have the following simple function:

pub fn edit_qm_atoms(pdb: &mut PDB, qm_val: f64, list: Vec<usize>) -> Result<(), Box<dyn Error>> {
    // for atom in pdb.atoms_mut() {
    //     // if list.find(|x| x == atom).is_some() {
    //     if list.contains(&atom.serial_number()) {
    //         atom.set_occupancy(qm_val)?
    //     }
    // }

    // pdb.par_atoms_mut().for_each(|atom| {
    //     if list.contains(&atom.serial_number()) {
    //         atom.set_occupancy(qm_val).unwrap();
    //     }
    // });

    pdb.par_atoms_mut().for_each(|atom: &mut Atom| -> Result<(), Box<dyn Error>> {
        if list.contains(&atom.serial_number()) {
            atom.set_occupancy(qm_val)?;
        };
        Ok(())
    });
    Ok(())

Initially it was just a small for loop (first comment) which I wanted to rewrite using an iterator because I want to parallelize it with rayon. However, I always stumble over the error handling within. It works if I use unwrap(second comment) but when I tried to get rid of that I get type mismatching because Rust tells me it expected a Result type and got (). However I don't understand what's wrong here.

P.S. I know there are other issues like this in the forum but even so I couldn't get it to work.

Using ? in a closure returns from the closure, not the surrounding function, and for_each's closure is not allowed to return anything.

try_for_each does allow you to return a Result - you should use that instead.

3 Likes

Thanks, I missed that fact