while_!() { /* proc-macro */ }Expand description
The while_! procedural macro with enhanced loop control.
This macro is an extension of the standard while loop in Rust. It allows users to
have an additional else block that executes if the loop completed without encountering a break statement.
§Syntax
ⓘ
while_! { condition {
// loop body
} else {
// else block
}}
// With optional label:
while_! { 'label: condition {
// loop body
} else {
// else block
}}§Notes
- The macro supports all the same conditions as standard
whileloops - Loop labels work normally for controlling nested loops
- Complex expressions in the condition position are fully supported
§Behavior
- The loop continues to execute as long as the
conditionevaluates totrue - If the loop exits naturally (condition becomes
false), theelseblock is executed - If the loop exits via a
breakstatement, theelseblock is not executed continuestatements work normally and do not affect theelseblock execution
§Examples
§Basic usage
use for_else::while_;
let mut count = 0;
let mut found = false;
while_! { count < 5 {
if count == 10 { // This condition is never true
found = true;
break;
}
count += 1;
} else {
println!("Loop completed without finding target value");
}}
assert!(!found); // Loop completed naturally, else block executed§Search with early termination
use for_else::while_;
fn find_target(data: &[i32], target: i32) -> Option<usize> {
let mut index = 0;
let mut result = None;
while_! { index < data.len() {
if data[index] == target {
result = Some(index);
break; // Found it, exit early
}
index += 1;
} else {
println!("Target {} not found in data", target);
}}
result
}§Retry mechanism with timeout
use for_else::while_;
use std::time::{Duration, Instant};
fn retry_operation() -> bool {
let start = Instant::now();
let timeout = Duration::from_secs(5);
while_! { start.elapsed() < timeout {
if attempt_operation() {
println!("Operation succeeded!");
return true;
}
std::thread::sleep(Duration::from_millis(100));
} else {
println!("Operation timed out after 5 seconds");
}}
false
}
fn attempt_operation() -> bool {
// Some operation that might succeed or fail
false
}§Nested loops with labels
Labels should be put inside the macro
use for_else::while_;
let mut found_target = false;
let mut outer_count = 0;
while_! { 'outer: outer_count < 5 {
let mut inner_count = 0;
while_! { inner_count < 5 {
if outer_count == 2 && inner_count == 3 {
println!("Found target at ({}, {})", outer_count, inner_count);
found_target = true;
break 'outer; // Break outer loop
}
inner_count += 1;
} else {
println!("Inner loop completed for outer_count = {}", outer_count);
}}
outer_count += 1;
} else {
println!("Search completed without early termination");
}}
assert!(found_target);§Comparison with Python
This macro brings Python-like while-else behavior to Rust:
Python:
while condition:
# loop body
if some_condition:
break
else:
# executed if loop completed without break
passRust with while_!:
ⓘ
while_! { condition {
// loop body
if some_condition {
break;
}
} else {
// executed if loop completed without break
}}