Macro loop_let

Source
macro_rules! loop_let {
    ($pattern:pat = $initial:expr; $body:block) => { ... };
    (fails $pattern:pat = $initial:expr; $body:block) => { ... };
}
Expand description

Implementation of the loop let immutable loop pattern. This implements a loop that is meant for tail call recursive algorithms earning tail call optimization for free.

The syntax is as follows:

loop_let!((pattern) = (initial); { 
    // code ... 
});

The pattern is the pattern that will be matched against the input. The initial is the initial value of the input. The code block is the code that will be executed in every iteration of loop. It’s important to notice that the code block must return either a Continue or a Break.

Continue is used to set the input value for the next iteration of the loop. Break is used to break the loop and return the value.

When using fallible patterns, the fails keyword must be used before the pattern. This way, the loop breaks once the pattern fails. By using the fails keyword, the loop_let macro will return () (this means you can only use Break(())). So it can’t be used as an expression.

§Panics

If a fallible pattern is used without the fails keyword, the loop will panic once the pattern matching fails.

§Example

use loop_let::loop_let;
 
let fib = loop_let!((n, curr, next) = (6, 0, 1); {
    if n == 0 {
       Break(curr)
    } else {
       Continue((n - 1, next, curr + next))
    }
});
 
assert_eq!(fib, 8);