Skip to main content

rustidy_ast/item/
macro_rules.rs

1//! Macro rules
2
3// Imports
4use {
5	crate::{
6		attr::DelimTokenTree,
7		token::{self, Token},
8		util::{Braced, Bracketed, Parenthesized},
9	},
10	rustidy_ast_util::{
11		AtLeast1,
12		Identifier,
13		IdentifierOrKeyword,
14		PunctuatedTrailing,
15		RawIdentifier,
16		at_least,
17		delimited,
18		punct,
19	},
20	rustidy_format::{Format, Formattable, WhitespaceFormat},
21	rustidy_parse::{Parse, ParserTag},
22	rustidy_print::Print,
23	rustidy_util::Whitespace,
24};
25
26/// `MacroRulesDefinition`
27#[derive(PartialEq, Eq, Clone, Debug)]
28#[derive(serde::Serialize, serde::Deserialize)]
29#[derive(Parse, Formattable, Format, Print)]
30pub struct MacroRulesDefinition {
31	pub macro_rules: token::MacroRules,
32	#[parse(fatal)]
33	#[format(prefix_ws = Whitespace::REMOVE)]
34	pub not:         token::Not,
35	#[format(prefix_ws = Whitespace::SINGLE)]
36	pub ident:       Identifier,
37	#[format(prefix_ws = Whitespace::SINGLE)]
38	#[format(indent)]
39	pub def:         MacroRulesDef,
40}
41
42/// `MacroRulesDef`
43#[derive(PartialEq, Eq, Clone, Debug)]
44#[derive(serde::Serialize, serde::Deserialize)]
45#[derive(Parse, Formattable, Format, Print)]
46pub enum MacroRulesDef {
47	Parens(MacroRulesDefParens),
48	Brackets(MacroRulesDefBrackets),
49	Braces(MacroRulesDefBraces),
50}
51
52#[derive(PartialEq, Eq, Clone, Debug)]
53#[derive(serde::Serialize, serde::Deserialize)]
54#[derive(Parse, Formattable, Format, Print)]
55pub struct MacroRulesDefParens {
56	#[format(args = delimited::fmt_preserve())]
57	pub rules: Parenthesized<MacroRules>,
58	pub semi:  token::Semi,
59}
60
61#[derive(PartialEq, Eq, Clone, Debug)]
62#[derive(serde::Serialize, serde::Deserialize)]
63#[derive(Parse, Formattable, Format, Print)]
64pub struct MacroRulesDefBrackets {
65	#[format(args = delimited::fmt_preserve())]
66	pub rules: Bracketed<MacroRules>,
67	pub semi:  token::Semi,
68}
69
70#[derive(PartialEq, Eq, Clone, Debug)]
71#[derive(serde::Serialize, serde::Deserialize)]
72#[derive(Parse, Formattable, Format, Print)]
73pub struct MacroRulesDefBraces {
74	#[format(args = delimited::fmt_preserve())]
75	pub rules: Braced<MacroRules>,
76}
77
78/// `MacroRules`
79#[derive(PartialEq, Eq, Clone, Debug)]
80#[derive(serde::Serialize, serde::Deserialize)]
81#[derive(Parse, Formattable, Format, Print)]
82pub struct MacroRules(
83	#[format(args = punct::fmt(Whitespace::PRESERVE, Whitespace::PRESERVE))]
84	PunctuatedTrailing<MacroRule, token::Semi>,
85);
86
87/// `MacroRule`
88#[derive(PartialEq, Eq, Clone, Debug)]
89#[derive(serde::Serialize, serde::Deserialize)]
90#[derive(Parse, Formattable, Format, Print)]
91pub struct MacroRule {
92	pub matcher:     MacroMatcher,
93	#[parse(fatal)]
94	#[format(prefix_ws = Whitespace::SINGLE)]
95	pub arrow:       token::FatArrow,
96	#[format(prefix_ws = Whitespace::SINGLE)]
97	pub transcriber: MacroTranscriber,
98}
99
100/// `MacroMatcher`
101#[derive(PartialEq, Eq, Clone, Debug)]
102#[derive(serde::Serialize, serde::Deserialize)]
103#[derive(Parse, Formattable, Format, Print)]
104pub enum MacroMatcher {
105	#[format(args = delimited::fmt_preserve())]
106	Parens(Parenthesized<MacroMatcherMatches>),
107	#[format(args = delimited::fmt_preserve())]
108	Brackets(Bracketed<MacroMatcherMatches>),
109	#[format(args = delimited::fmt_preserve())]
110	Braces(Braced<MacroMatcherMatches>),
111}
112
113#[derive(PartialEq, Eq, Clone, Debug)]
114#[derive(serde::Serialize, serde::Deserialize)]
115#[derive(Parse, Formattable, Format, Print)]
116pub struct MacroMatcherMatches(
117	#[format(args = rustidy_format::vec::args_prefix_ws(Whitespace::PRESERVE))]
118	Vec<MacroMatch>,
119);
120
121/// `MacroMatch`
122#[derive(PartialEq, Eq, Clone, Debug)]
123#[derive(serde::Serialize, serde::Deserialize)]
124#[derive(Parse, Formattable, Format, Print)]
125pub enum MacroMatch {
126	#[parse(with_tag = ParserTag::SkipTokenDollar)]
127	#[parse(with_tag = ParserTag::SkipDelimiters)]
128	Token(Token),
129
130	Matcher(MacroMatcher),
131
132	DollarIdent(MacroMatchDollarIdent),
133	DollarRep(MacroMatchDollarRep),
134
135	// Note: The reference says we shouldn't allow `$` here, but
136	//       the compiler does, so we do as well, just with lower
137	//       priority
138	Dollar(token::Dollar),
139}
140
141#[derive(PartialEq, Eq, Clone, Debug)]
142#[derive(serde::Serialize, serde::Deserialize)]
143#[derive(Parse, Formattable, Format, Print)]
144pub struct MacroMatchDollarIdent {
145	pub dollar: token::Dollar,
146	#[format(prefix_ws = Whitespace::PRESERVE)]
147	pub ident:  MacroMatchDollarIdentInner,
148	#[parse(fatal)]
149	#[format(prefix_ws = Whitespace::PRESERVE)]
150	pub colon:  token::Colon,
151	#[format(prefix_ws = Whitespace::PRESERVE)]
152	pub spec:   MacroFragSpec,
153}
154
155#[derive(PartialEq, Eq, Clone, Debug)]
156#[derive(serde::Serialize, serde::Deserialize)]
157#[derive(Parse, Formattable, Format, Print)]
158pub enum MacroMatchDollarIdentInner {
159	Raw(RawIdentifier),
160	#[parse(with_tag = ParserTag::SkipTokenCrate)]
161	IdentOrKw(IdentifierOrKeyword),
162	Underscore(token::Underscore),
163}
164
165/// `MacroFragSpec`
166#[derive(PartialEq, Eq, Clone, Debug)]
167#[derive(serde::Serialize, serde::Deserialize)]
168#[derive(Parse, Formattable, Format, Print)]
169pub enum MacroFragSpec {
170	Block(token::Block),
171	Expr(token::Expr),
172	Expr2021(token::Expr2021),
173	Ident(token::Ident),
174	Item(token::Item),
175	Lifetime(token::Lifetime),
176	Literal(token::Literal),
177	Meta(token::Meta),
178	Pat(token::Pat),
179	PatParam(token::PatParam),
180	Path(token::Path),
181	Stmt(token::Stmt),
182	Tt(token::Tt),
183	Ty(token::Ty),
184	Vis(token::Vis),
185}
186
187#[derive(PartialEq, Eq, Clone, Debug)]
188#[derive(serde::Serialize, serde::Deserialize)]
189#[derive(Parse, Formattable, Format, Print)]
190pub struct MacroMatchDollarRep {
191	pub dollar:  token::Dollar,
192	#[format(prefix_ws = Whitespace::PRESERVE)]
193	#[format(args = delimited::fmt_preserve())]
194	pub matches: Parenthesized<MacroMatchDollarRepMatches>,
195	#[parse(fatal)]
196	#[format(prefix_ws = Whitespace::PRESERVE)]
197	pub rep_sep: Option<MacroRepSep>,
198	#[format(prefix_ws = Whitespace::PRESERVE)]
199	pub rep_op:  MacroRepOp,
200}
201
202#[derive(PartialEq, Eq, Clone, Debug)]
203#[derive(serde::Serialize, serde::Deserialize)]
204#[derive(Parse, Formattable, Format, Print)]
205pub struct MacroMatchDollarRepMatches(
206	#[format(args = at_least::fmt_prefix_ws(Whitespace::PRESERVE))]
207	pub AtLeast1<Box<MacroMatch>>,
208);
209
210/// `MacroRepSep`
211#[derive(PartialEq, Eq, Clone, Debug)]
212#[derive(serde::Serialize, serde::Deserialize)]
213#[derive(Parse, Formattable, Format, Print)]
214pub struct MacroRepSep(
215	#[parse(with_tag = ParserTag::SkipDelimiters)]
216	#[parse(with_tag = ParserTag::SkipTokenStar)]
217	#[parse(with_tag = ParserTag::SkipTokenPlus)]
218	#[parse(with_tag = ParserTag::SkipTokenQuestion)]
219	Token,
220);
221
222/// `MacroRepOp`
223#[derive(PartialEq, Eq, Clone, Debug)]
224#[derive(serde::Serialize, serde::Deserialize)]
225#[derive(Parse, Formattable, Format, Print)]
226pub enum MacroRepOp {
227	Star(token::Star),
228	Plus(token::Plus),
229	Question(token::Question),
230}
231
232/// `MacroTranscriber`
233#[derive(PartialEq, Eq, Clone, Debug)]
234#[derive(serde::Serialize, serde::Deserialize)]
235#[derive(Parse, Formattable, Format, Print)]
236pub struct MacroTranscriber(DelimTokenTree);