Macro syn::cond_reduce [] [src]

macro_rules! cond_reduce {
    ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => { ... };
    ($i:expr, $cond:expr) => { ... };
    ($i:expr, $cond:expr, $f:expr) => { ... };
}

Execute a parser only if a condition is met, otherwise fail to parse.

This is typically used inside of option! or alt!.

The subparser may be omitted in which case it defaults to epsilon!.

#[macro_use]
extern crate syn;

use syn::Type;
use syn::token::Paren;
use syn::punctuated::Punctuated;
use syn::synom::Synom;

/// Parses a possibly variadic function signature.
///
/// Example: `fn(A) or `fn(A, B, C, ...)` or `fn(...)`
/// Rejected: `fn(A, B...)`
struct VariadicFn {
    fn_token: Token![fn],
    paren_token: Paren,
    types: Punctuated<Type, Token![,]>,
    variadic: Option<Token![...]>,
}

// Example of using `cond_reduce!` inside of `option!`.
impl Synom for VariadicFn {
    named!(parse -> Self, do_parse!(
        fn_token: keyword!(fn) >>
        params: parens!(do_parse!(
            types: call!(Punctuated::parse_terminated) >>
            // Allow, but do not require, an ending `...` but only if the
            // preceding list of types is empty or ends with a trailing comma.
            variadic: option!(cond_reduce!(types.empty_or_trailing(), punct!(...))) >>
            (types, variadic)
        )) >>
        ({
            let (paren_token, (types, variadic)) = params;
            VariadicFn {
                fn_token,
                paren_token,
                types,
                variadic,
            }
        })
    ));
}

This macro is available if Syn is built with the "parsing" feature.