You write a function-like procedural macro by defining a proc-macro crate with a single function annotated with #[proc_macro] that takes a TokenStream and returns a Result<TokenStream>.
// In a new crate with `proc-macro = true` in Cargo.toml
use proc_macro::TokenStream;
#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {
// Transform input tokens here
input
}
Add the macro crate as a dependency in your main project's Cargo.toml and call it like a function: my_macro!();.