konst

Macro rebind_if_ok

Source
macro_rules! rebind_if_ok {
    (
        $pattern:tt $(:$ty:ty)? = $expression:expr
        $( => $($code:tt)* )?
    ) => { ... };
}
Available on crate feature parsing only.
Expand description

Like an if let Ok, but also reassigns variables with the value in the Ok variant.

Note: the Ok variant can only be destructured into a single variable or a tuple.

§Let pattern

You can declare variables usable inside this macro with let patterns, like this:

let res: Result<_, ()> = Ok((10, 20));
rebind_if_ok!{(let foo, bar) = res =>
    number += foo;
}

foo in this invocation of rebind_if_ok is a macro-local variable initialized with 10, while bar is a pre-existing variable that is assigned 20.

This pattern only works when destructuring tuples.

§Example

use konst::{
    parsing::{Parser, ParseValueResult},
    rebind_if_ok,
};

#[derive(Debug, PartialEq)]
struct Struct {
    foo: bool,
    bar: bool,
    baz: Option<u64>,
}

const fn parse_struct(mut parser: Parser<'_>) -> (Struct, Parser<'_>) {
    let mut flags = Struct {
        foo: false,
        bar: false,
        baz: None,
    };

    // `parser` is reassigned if the `strip_prefix` method returns an `Ok` variant.
    // (this also happens in every other invocation of `rebind_if_ok` in this example)
    rebind_if_ok!{parser = parser.strip_prefix("foo,") =>
        flags.foo = true;
    }
    rebind_if_ok!{parser = parser.strip_prefix("bar,") =>
        flags.bar = true;
    }
    // `num` is only visible inside this macro invocation
    rebind_if_ok!{(let num, parser) = parser.parse_u64() =>
        flags.baz = Some(num);
    }
    (flags, parser)
}

const XX: [Struct; 2] = {
    [
        parse_struct(Parser::new("foo,1000")).0,
        parse_struct(Parser::new("bar,")).0,
    ]
};

assert_eq!(
    XX,
    [
        Struct{foo: true, bar: false, baz: Some(1000)},
        Struct{foo: false, bar: true, baz: None},
    ]
);