Macro tt_call::tt_if

source ·
macro_rules! tt_if {
    {
        condition = [{ $($condition:ident)::* }]
        input = [{ $($input:tt)* }]
        true = [{ $($then:tt)* }]
        false = [{ $($else:tt)* }]
    } => { ... };
}
Expand description

Evaluate a condition and expand to one or the other of two branches.

Input

  • condition = [{ name of predicate macro to invoke }]
  • input = [{ arbitrary tokens to pass as input to the predicate }]
  • true = [{ tokens to expand to if the predicate returns true }]
  • false = [{ and if the predicate returns false }]

The predicate macro must accept a single input value named input. It is expected to return a single output value which may have any name but must hold the tokens true or false. For example the built-in tt_is_comma! predicate expands to is_comma = [{ true }] or is_comma = [{ false }].

Example

use tt_call::{tt_call, tt_if, tt_is_comma, tt_return};

macro_rules! parse_until_comma {
    ($($input:tt)*) => {
        tt_call! {
            macro = [{ parse_until_comma_helper }]
            before_comma = [{ }]
            tokens = [{ $($input)* }]
        }
    };
}

macro_rules! parse_until_comma_helper {
    {
        $caller:tt
        before_comma = [{ $($before:tt)* }]
        tokens = [{ $first:tt $($rest:tt)* }]
    } => {
        tt_if! {
            condition = [{ tt_is_comma }]
            input = [{ $first }]
            true = [{
                tt_return! {
                    $caller
                    before_comma = [{ $($before)* }]
                }
            }]
            false = [{
                parse_until_comma_helper! {
                    $caller
                    before_comma = [{ $($before)* $first }]
                    tokens = [{ $($rest)* }]
                }
            }]
        }
    };
}

fn main() {
    assert_eq!(3, parse_until_comma!(1 + 2, three, four));
}