type
status
slug
date
summary
tags
category
password
icon
proc-macro-workshop
KMSorSMS • Updated Aug 11, 2024
Project Path
If this is your first time working with procedural macros, I would recommend starting with thederive(Builder)
project. This will get you comfortable with traversing syntax trees and constructing output source code. These are the two fundamental components of a procedural macro.
I first do derive(Builder)
Derive macro: derive(Builder)
This macro generates the boilerplate code involved in implementing the builder pattern in Rust. Builders are a mechanism for instantiating structs, especially structs with many fields, and especially if many of those fields are optional or the set of fields may need to grow backward compatibly over time.There are a few different possibilities for expressing builders in Rust. Unless you have a strong pre-existing preference, to keep things simple for this project I would recommend following the example of the standard library'sstd::process::Command
builder in which the setter methods each receive and return&mut self
to allow chained method calls. Callers will invoke the macro as follows.This project covers:
- traversing syntax trees;
- constructing output source code;
- processing helper attributes to customize the generated code.
Project skeleton is located under thebuilder
directory.
01 the DeriveInput
Struct syn::Attribute
Rust has six types of attributes.
- Outer attributes like
#[repr(transparent)]
. These appear outside or in front of the item they describe.
- Inner attributes like
#![feature(proc_macro)]
. These appear inside of the item they describe, usually a module.
- Outer one-line doc comments like
/// Example
.
- Inner one-line doc comments like
//! Please file an issue
.
- Outer documentation blocks
/** Example */
.
- Inner documentation blocks
/*! Please file an issue */
.
The
style
field of type AttrStyle
distinguishes whether an attribute is outer or inner.Enum syn::AttrStyle
Outer attributes
#[repr(transparent)]
/// # Example
/** Please file an issue */
Inner attributes
#![feature(proc_macro)]
//! # Example
/*! Please file an issue */
Struct syn::token::Pound
Enum syn::Meta
Path
A meta path is like the
test
in #[test]
.List
A meta list is like the
derive(Copy)
in #[derive(Copy)]
.NameValue
A name-value meta is like the
path = "..."
in #[path = "sys/windows.rs"]
.02-create-builder
quote
dtolnay • Updated Sep 13, 2024
Joining together the type name + "Builder" to make the builder's name:
- 作者:liamY
- 链接:https://liamy.clovy.top/article/notes/proc-macro-workshop
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。