I created a "simplified version" of my menu in the playground.
As you can see there's an "install" option that starts
"firing off installation commands".
Trouble is is when there's an error in one of those commands,
it needs to go to show an error box and then go back to the main menu.
I've got issues with this because I've already written the install sequence as
a nested iterator and with so many variables to keep track of (i, j, command_group, command, text), I'm getting lost on how properly write a loop for this thing anymore.
But I do get the feeling I should get rid of it and write a nested for loop instead.
Just know that you can always rewrite iterator.for_each(|value| { body } into a loop:
for value in iterator {
body
}
In this case this leads to something like this:
for (i, (text, command_group)) in command_groups.iter().enumerate() {
let percent = i * 100 / cg_len;
println!("Install step: {}\nAt {}%", text, percent);
for (j, command) in command_group.iter().enumerate() {
match command {
&"do_command_2_0" => {}, // return Page::InstallError
_ => println!("Executing command #{}: {}", j, command),
}
}
}
Now you can return or break from the loop.
You could also use try_for_each so that you can break out of the loop.
Since I'm not sure what you're asking, I'm also giving the tip that you can break out of the outer loop from the inner loop using labeled loops and breaks: Nesting and labels - Rust By Example
There's a point where return Page::InstallError
needs to be called, for example,
when the folder can not be found it needs to install to,
instead of Page::Finish.
So I do a match command.prepare() to see what next step needs to be made,
The 'command' in my example is named option_command in my actual code,
as the option execute zero, one or multiple commands
depending on the result of the prepare method.
I can't call return page within a closure as it starts complaining about types not matching,
That's because a return statement is scoped to the closure (which is basically its own function). break and continue won't work for the same reason (though continue; can be emulated with return;.