liveBook · Manning

Parse2

As explained in Write Powerful Rust Macros

parse2 is a syn function that parses a proc-macro2 token stream into a specified Rust syntax type and checks that the input has been fully consumed.

`syn::parse2` parses a `proc_macro2::TokenStream` as a chosen Rust syntax type that implements `Parse`. Its generic type makes the intended AST explicit, such as `parse2::<StructField>(tokens)`, and parsing fails when the tokens do not fit that type. section 4.6.2

Use `parse2` when macro logic runs outside a procedural-macro crate and therefore works with the `proc_macro2` wrapper. Parse the incoming tokens into `DeriveInput`, extract the annotated type name, and generate a collision-resistant helper name with `format_ident!`. section 6.2

Common patterns and trade-offs:

  • Parse a field token stream into a custom `StructField` with `parse2::<StructField>(f.to_token_stream())`. This works, but converting an already parsed field back into tokens is awkward; parsing all fields into custom structures can avoid it. section 4.6.2
  • Parse generated output in a white-box test, then inspect the resulting AST. A failed parse panics through `unwrap`, while a successful parse makes identifiers and other syntax data easy to assert. section 6.3
  • Prefer quoted expected output when generated code contains multiple items, because parsing such output can require custom test logic. section 6.3

Parse derive input in helper code

A helper crate can accept `proc_macro2::TokenStream`, parse it as `DeriveInput`, and use `ast.ident` to construct generated code: `let ast: DeriveInput = syn::parse2(item).unwrap();` `let builder = format_ident!("{}Builder", ast.ident);` The procedural-macro entry point converts its `proc_macro::TokenStream` into the wrapper type before calling that helper. section 6.2

Listing 6.2 The lib.rs file in builder-code
use proc_macro2::{TokenStream};
use quote::{format_ident, quote, ToTokens};
use syn::DeriveInput;

pub fn create_builder(item: TokenStream) -> TokenStream {
    let ast: DeriveInput = syn::parse2(item).unwrap();    #1
    let name = ast.ident;
    let builder = format_ident!("{}Builder", name);       #2

    quote! {
        struct #builder {}                  #3
    }
}

This listing shows the minimal helper: parse a `proc_macro2` stream into `DeriveInput`, derive a builder identifier, and emit a helper struct with `quote!`. section 6.2

How Write Powerful Rust Macros covers it

How deep it goes
Demonstrates typed target selection and error unwrapping, while deferring custom parsing needed for multiple generated items.
Examples
Uses StructField parsing, a generated builder struct, and a test that parses generated output as DeriveInput.
What it assumes
Assumes Rust testing basics while introducing parse target annotations and proc_macro2-based macro helper parsing.
What you can do after
Apply it via syn::parse2 to obtain DeriveInput or StructField ASTs from proc_macro2 tokens.
How it connects
Connects Parse, TokenStream, proc_macro2, DeriveInput, quote, and white-box testing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Write Powerful Rust Macros. The section links point to the parts of the book it draws on.