A function-like macro is a Rust procedural macro called with `!` that accepts token input and replaces it with generated tokens. Unlike derive and attribute macros, it is not confined to decorating particular Rust items, so it can be invoked almost anywhere code can appear. That freedom makes it useful for transformations that do not begin with a struct, enum, trait, or function. section 1.3.1 section 5.7
Figure 1.2 The types of macros in Rust
Compare function-like macros with derive and attribute procedural macros before choosing how much input freedom and transformation power a task needs. section 1.3.1
Define one with `#[proc_macro]` and a function taking one `TokenStream` and returning one. Parse the incoming tokens into a `syn` type, inspect the resulting syntax tree, then use `quote!` to emit replacement code. Because arbitrary input may not be valid Rust, a general-purpose parser such as `DeriveInput` is often insufficient; define a custom parser when the macro accepts its own notation. section 5.1.1 section 5.3
Generate an information-hiding struct API
A call such as `private!(struct Example { string_value: String, number_value: i32, });` can receive the complete struct definition. Its expansion recreates the struct and its implementation, allowing generated accessor methods while controlling which details remain exposed. The original invocation disappears, so the output must include every item needed by the caller. section 5.1.1
Accept a mini-language for composition
`compose!(add_one . add_one . stringify)` accepts dot-separated identifiers that are not an ordinary Rust composition expression. A custom `ComposeInput` parser reads identifiers punctuated by `.`, while token generation emits a block containing a helper function and the composed closure. The block is necessary so the expansion evaluates as one value for a `let` binding. section 5.3
Choose a macro form by the transformation required:
- Use a derive macro when adding functionality to a struct or enum without changing it. section 5.4
- Use an attribute macro when altering an annotated struct, enum, trait, or function. section 5.4
- Use a function-like macro when input may be broader than annotated items or when it must change functionality in other contexts. section 5.4
Treat generated code as code that must compile on its own. When expansion errors are confusing, write the intended generated Rust manually first and let the compiler or IDE identify problems. Prefer the simplest macro that meets the requirements: broad input makes function-like macros flexible, but also increases parsing work and makes their effects less predictable than narrower procedural macros. section 5.7 section 5.4
Generate configuration storage
A `config` macro can turn YAML-style plain string key-value properties into a generated `Config` struct holding `HashMap<String, String>` data and a method that fills it. Restricting the accepted configuration to non-nested values keeps the input format and generated API deliberately simple. section 10.1


