I have a list of ChildWorker
elements, as Vec<ChildWorker>
, where:
struct ChildWorker {
child: process::Child,
files: Vec<PathBuf>
}
I want to extract from the Vec<ChildWorker>
all the elements where child.try_wait()
is Ok(Some(_))
. (Can't use Vec::extract_if()
, because that's still baking in the oven).
This was my plan:
- Assume
let mut childworkers: Vec<ChildWorker> = Vec::new();
- Iterate over elements and gather a list of indexes for elements that have run to completion:
let mut idxes = Vec::new(); for (idx, cw) in childworkers.iter().enumerate() { if let Ok(Some(_)) = cw.child.try_wait() { idxes.push(idx); } }
- Reverse the order of
idxes
, to avoid renumbering chaos:idxes.reverse();
- Move element by
idxes
to generate output list:let mut out = Vec::new(); for idx in idxes { out.push(childworkers.swap_remove(idx)); }
T'was a nice plan, but was foiled by Child::try_wait()
being &mut self
, upsetting the horror-chucker.
There's a pretty straight-forward solution to this: Extract all elements from the childworkers and run try_wait()
on the extracted element and put back the ones that are not completed. But this feels a little derpy -- though realistically it's not that bad, because there's a debouncer involved so it won't run very often, and the performance hit for moving all elements around is vanishingly small compared to spawning the child workers. With that said: Is there any way to simulate something more extract_if()
-like using whatever is available in (stable) std?