vacro-parser 0.1.8

A declarative parsing library for Rust procedural macros, simplifying input handling.
Documentation

Vacro Parser

The Declarative Parsing Kernel for Vacro

crates.io docs.rs

Introduction

Vacro Parser is the core declarative parsing engine of the Vacro framework. It provides a macro_rules!-like DSL to simplify the writing of syn-based parsers for Rust Procedural Macros.

It allows you to define AST structures and parsing logic declaratively, eliminating the boilerplate of imperative input.parse()? calls.

Installation

Add this to your Cargo.toml:

[dependencies]
vacro-parser = "0.1.8"

Core Features

1. define!: Define Parsing Structs

Use define! to define a struct that automatically implements syn::parse::Parse.

use syn::{Ident, Type, GenericParam, FnArg, parse_quote};

// Define a struct named MyFn, it automatically implements the Parse trait
vacro::define!(MyFn:
    fn
    #(?: <#(generic*[,]: GenericParam)>)
    #(name: Ident)
    ( #(args*[,]: FnArg) )
    #(?: -> #(ret: Type))
);

// Usage in a proc-macro
fn parse_my_fn(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
    let my_fn: MyFn = parse_quote!(input);
    println!("Function name: {}", my_fn.name);
    proc_macro2::TokenStream::new()
}

2. bind!: On-the-fly Parsing

Use bind! to consume a portion of a TokenStream within existing imperative logic.

use syn::{Ident, Type, Token};
use vacro_parser::bind;

fn parser(input: syn::parse::ParseStream) -> syn::Result<()> {
    // Parse a function signature pattern on the fly
    bind!(
        let captured = (input ->
            fn #(name: Ident) #(?: -> #(ret: Type))
        )?;
    );

    // Access captured fields directly
    println!("Name: {}", captured.name);
    if let Some(ret_type) = captured.ret {
        // ...
    }
    Ok(())
}

Syntax Reference

Syntax Description Example
literal Matches exact tokens fn, ->, struct
#(x: T) Named Capture: Captures type T into field x #(name: Ident)
#(x?: T) Optional Capture: Option<T> #(ret?: Type)
#(x*[sep]: T) Iterative Capture: Punctuated<T, sep> #(args*[,]: FnArg)
#(T) Anonymous Match: Validates T exists but doesn't capture #(Ident)

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

More user-friendly prompts (v0.1.6)

You can use the help! macro of vacro-report to provide more helpful suggestions for the content. If you are using vacro, you only need to enable the report feature.

vacro_parser = { version = "0.1.8" }
vacro_report = { version = "0.1.3", features = ["parser"] }

# vacro = { version = "0.2.3", features = ["parser", "report"] }
use vacro_parser::define;
use vacro_report::help;
use syn::{Ident, LitBool};

help!(Bool:
    LitBool {
        error: "A boolean literal is required here; the received value is: {input}".
        help: "Try `true` or `false`",
        example: (true | false) // The example field is the sample field to be displayed, used when generating error messages and usage examples; it accepts a TokenStream and will directly display the content you pass in.
    }
);

define!(MyRoles: {
    #(roles*[,]: #(pair: #(name: Ident): #(enable: Bool)))
});