Skip to main content

bind

Macro bind 

Source
bind!() { /* proc-macro */ }
Expand description

On-the-fly parsing macro: Quickly consume a TokenStream within existing parsing logic

The bind! macro mimics a let binding statement. The core expression (<input> -> <pattern>) expands to a block that evaluates to syn::Result<Output>.

This means you can treat it like any other Result expression, appending ?, .unwrap(), or .map(...) directly after it.

§Syntax

vacro::bind!(let <binding> = (<input> -> <pattern>) <operations>);
  • binding: Standard Rust pattern to receive the parsed content (e.g., res or (a, b)).
  • input: A variable implementing Into<TokenStream>.
  • pattern: The Vacro pattern description.
  • operations: Operations on the Result, such as ?;, .unwrap();, etc.

§Capture Rules

  • Named Capture (#(name: Type)): Generates a temporary Output struct containing these fields.
  • Inline Capture (#(@: Type)): Returns a tuple (or single value) containing captured items in order.

§Example

fn parser(input: TokenStream) -> Result<()> {
    // Case 1: Using with `?` (Recommended)
    // The expression `(input -> ...)` returns Result, `?` propagates error
    let input1 = input.clone();
    bind!(
        let func = (input1 -> fn #(name: Ident))?;
    );
    println!("Function: {}", func.name);

    // Case 2: Using with `unwrap`
    // If you are sure parsing will succeed
    let input2 = input.clone();
    bind!(
        let (arrow, ty) = (input2 -> #(@: Token![->]) #(@: Type)).unwrap();
    );

    // Case 3: Manually handling Result
    let input3 = input.clone();
    bind!(
        let result = (input3 -> #(kw: Token![mod]));
    );
    if let Ok(output) = result {
        // ...
    }

    Ok(())
}