doppleganger_macros_parse/lib.rs
1pub use unsynn::*;
2
3#[cfg(test)]
4mod tests;
5
6keyword! {
7 /// The "pub" keyword.
8 pub KPub = "pub";
9 /// The "struct" keyword.
10 pub KStruct = "struct";
11 /// The "enum" keyword.
12 pub KEnum = "enum";
13 /// The "doc" keyword.
14 pub KDoc = "doc";
15 /// The "repr" keyword.
16 pub KRepr = "repr";
17 /// The "crate" keyword.
18 pub KCrate = "crate";
19 /// The "in" keyword.
20 pub KIn = "in";
21 /// The "const" keyword.
22 pub KConst = "const";
23 /// The "where" keyword.
24 pub KWhere = "where";
25 /// The "mut" keyword.
26 pub KMut = "mut";
27 pub KDg = "dg";
28 /// The "default" keyword.
29 pub KDefault = "default";
30 /// The "rename" keyword.
31 pub KRename = "rename";
32 /// The "flatten" keyword
33 pub KFlatten = "flatten";
34 /// The "forward" keyword
35 pub KForward = "forward";
36 /// The "backward" keyword
37 pub KBackward = "backward";
38 /// the "ignore" keywoard
39 pub KIgnore = "ignore";
40 /// the "map" keyword
41 pub KMap = "map"
42}
43
44operator! {
45 /// Represents the '=' operator.
46 pub Eq = "=";
47 /// Represents the ';' operator.
48 pub Semi = ";";
49 /// Represents the apostrophe '\'' operator.
50 pub Apostrophe = "'";
51 /// Represents the double semicolon '::' operator.
52 pub DoubleSemicolon = "::";
53}
54
55/// Parses tokens and groups until `C` is found on the current token tree level.
56pub type VerbatimUntil<C> = Many<Cons<Except<C>, AngleTokenTree>>;
57
58/// Represents a module path, consisting of an optional path separator followed by
59/// a path-separator-delimited sequence of identifiers.
60pub type ModPath = Cons<Option<PathSep>, DelimitedVec<Ident, PathSep>>;
61
62/// Represents type bounds, consisting of a colon followed by tokens until
63/// a comma, equals sign, or closing angle bracket is encountered.
64pub type Bounds = Cons<Colon, VerbatimUntil<Either<Comma, Eq, Gt>>>;
65
66unsynn! {
67 /// Parses either a `TokenTree` or `<...>` grouping (which is not a [`Group`] as far as proc-macros
68 /// are concerned).
69 #[derive(Clone)]
70 pub struct AngleTokenTree(
71 #[allow(clippy::type_complexity)] // look,
72 pub Either<Cons<Lt, Vec<Cons<Except<Gt>, AngleTokenTree>>, Gt>, TokenTree>,
73 );
74
75 /// Represents an algebraic data type (ADT) declaration, which can be either a struct or enum.
76 pub enum AdtDecl {
77 /// A struct ADT variant.
78 Struct(Struct),
79 /// An enum ADT variant.
80 Enum(Enum),
81 }
82
83 /// Represents visibility modifiers for items.
84 pub enum Vis {
85 /// `pub(in? crate::foo::bar)`/`pub(in? ::foo::bar)`
86 PubIn(Cons<KPub, ParenthesisGroupContaining<Cons<Option<KIn>, ModPath>>>),
87 /// Public visibility, indicated by the "pub" keyword.
88 Pub(KPub),
89 }
90
91 /// Represents an attribute annotation on a field, typically in the form `#[attr]`.
92 pub struct Attribute {
93 /// The pound sign preceding the attribute.
94 pub _pound: Pound,
95 /// The content of the attribute enclosed in square brackets.
96 pub body: BracketGroupContaining<AttributeInner>,
97 }
98
99 /// Represents the inner content of an attribute annotation.
100 pub enum AttributeInner {
101 /// A dopplegagner attribute that can contain specialized metadata.
102 Dg(DopplegangerAttr),
103 /// A documentation attribute typically used for generating documentation.
104 Doc(DocInner),
105 /// A representation attribute that specifies how data should be laid out.
106 Repr(ReprInner),
107 /// Any other attribute represented as a sequence of token trees.
108 Any(Vec<TokenTree>),
109 }
110
111 /// Represents a dg attribute that can contain specialized metadata.
112 pub struct DopplegangerAttr {
113 /// The keyword for the dg attribute.
114 pub _dg: KDg,
115 /// The inner content of the dg attribute.
116 pub inner: ParenthesisGroupContaining<CommaDelimitedVec<DgInner>>,
117 }
118
119 /// Represents the inner content of a dg attribute.
120 pub enum DgInner {
121 /// The direction of the source/dest relation
122 Direction(DgDirection),
123 /// A default attribute with an explicit value (#[dg(default = "myfunc")])
124 DefaultEquals(DefaultEqualsInner),
125 /// A default attribute with no explicit value (#[dg(default)])
126 Default(KDefault),
127 /// A rename attribute that specifies a custom name for a field/variant (#[dg(rename = "custom_name")])
128 Rename(RenameInner),
129 /// Ignore the field in the forward direction
130 Ignore(KIgnore),
131 /// map the field from one value to another
132 Map(DgMap)
133 }
134
135 pub struct DgMap {
136 _map: KMap,
137 _eq: Eq,
138 pub path: ModPath
139 }
140
141 pub enum DgDirection {
142 Forward {
143 _fw: KForward,
144 _eq: Eq,
145 path: ModPath
146 },
147 Backward {
148 _bw: KBackward,
149 _eq: Eq,
150 path: ModPath
151 }
152 }
153
154 /// Inner value for #[dg(flatten)]
155 pub struct FlattenInner {
156 /// The "flatten" keyword.
157 pub _kw_flatten: KFlatten,
158 }
159
160
161 /// Inner value for #[dg(default = ...)]
162 pub struct DefaultEqualsInner {
163 /// The "default" keyword.
164 pub _kw_default: KDefault,
165 /// The equals sign '='.
166 pub _eq: Eq,
167 /// The value assigned, as verbatim until comma.
168 pub expr: VerbatimUntil<Comma>,
169 }
170
171 /// Inner value for #[dg(rename = ...)]
172 pub struct RenameInner {
173 /// The "rename" keyword.
174 pub _kw_rename: KRename,
175 /// The equals sign '='.
176 pub _eq: Eq,
177 /// The value assigned, as a literal string.
178 pub value: LiteralString,
179 }
180
181 /// Represents documentation for an item.
182 pub struct DocInner {
183 /// The "doc" keyword.
184 pub _kw_doc: KDoc,
185 /// The equality operator.
186 pub _eq: Eq,
187 /// The documentation content as a literal string.
188 pub value: LiteralString,
189 }
190
191 /// Represents the inner content of a `repr` attribute, typically used for specifying
192 /// memory layout or representation hints.
193 pub struct ReprInner {
194 /// The "repr" keyword.
195 pub _kw_repr: KRepr,
196 /// The representation attributes enclosed in parentheses.
197 pub attr: ParenthesisGroupContaining<CommaDelimitedVec<Ident>>,
198 }
199
200 /// Represents a struct definition.
201 pub struct Struct {
202 /// Attributes applied to the struct.
203 pub attributes: Vec<Attribute>,
204 /// The visibility modifier of the struct (e.g., `pub`).
205 pub _vis: Option<Vis>,
206 /// The "struct" keyword.
207 pub _kw_struct: KStruct,
208 /// The name of the struct.
209 pub name: Ident,
210 /// Generic parameters for the struct, if any.
211 pub generics: Option<GenericParams>,
212 /// The variant of struct (unit, tuple, or regular struct with named fields).
213 pub kind: StructKind,
214 }
215
216 /// Represents the generic parameters of a struct or enum definition, enclosed in angle brackets.
217 /// e.g., `<'a, T: Trait, const N: usize>`.
218 pub struct GenericParams {
219 /// The opening angle bracket `<`.
220 pub _lt: Lt,
221 /// The comma-delimited list of generic parameters.
222 pub params: CommaDelimitedVec<GenericParam>,
223 /// The closing angle bracket `>`.
224 pub _gt: Gt,
225 }
226
227 /// Represents a single generic parameter within a `GenericParams` list.
228 pub enum GenericParam {
229 /// A lifetime parameter, e.g., `'a` or `'a: 'b + 'c`.
230 Lifetime {
231 /// The lifetime identifier (e.g., `'a`).
232 name: Lifetime,
233 /// Optional lifetime bounds (e.g., `: 'b + 'c`).
234 bounds: Option<Cons<Colon, VerbatimUntil<Either<Comma, Gt>>>>,
235 },
236 /// A const generic parameter, e.g., `const N: usize = 10`.
237 Const {
238 /// The `const` keyword.
239 _const: KConst,
240 /// The name of the const parameter (e.g., `N`).
241 name: Ident,
242 /// The colon separating the name and type.
243 _colon: Colon,
244 /// The type of the const parameter (e.g., `usize`).
245 typ: VerbatimUntil<Either<Comma, Gt, Eq>>,
246 /// An optional default value (e.g., `= 10`).
247 default: Option<Cons<Eq, VerbatimUntil<Either<Comma, Gt>>>>,
248 },
249 /// A type parameter, e.g., `T: Trait = DefaultType`.
250 Type {
251 /// The name of the type parameter (e.g., `T`).
252 name: Ident,
253 /// Optional type bounds (e.g., `: Trait`).
254 bounds: Option<Bounds>,
255 /// An optional default type (e.g., `= DefaultType`).
256 default: Option<Cons<Eq, VerbatimUntil<Either<Comma, Gt>>>>,
257 },
258 }
259
260 /// Represents a `where` clause attached to a definition.
261 /// e.g., `where T: Trait, 'a: 'b`.
262 #[derive(Clone)]
263 pub struct WhereClauses {
264 /// The `where` keyword.
265 pub _kw_where: KWhere,
266 /// The comma-delimited list of where clause predicates.
267 pub clauses: CommaDelimitedVec<WhereClause>,
268 }
269
270 /// Represents a single predicate within a `where` clause.
271 /// e.g., `T: Trait` or `'a: 'b`.
272 #[derive(Clone)]
273 pub struct WhereClause {
274 // FIXME: This likely breaks for absolute `::` paths
275 /// The type or lifetime being constrained (e.g., `T` or `'a`).
276 pub _pred: VerbatimUntil<Colon>,
277 /// The colon separating the constrained item and its bounds.
278 pub _colon: Colon,
279 /// The bounds applied to the type or lifetime (e.g., `Trait` or `'b`).
280 pub bounds: VerbatimUntil<Either<Comma, Semicolon, BraceGroup>>,
281 }
282
283 /// Represents the kind of a struct definition.
284 pub enum StructKind {
285 /// A regular struct with named fields, e.g., `struct Foo { bar: u32 }`.
286 Struct {
287 /// Optional where clauses.
288 clauses: Option<WhereClauses>,
289 /// The fields enclosed in braces `{}`.
290 fields: BraceGroupContaining<CommaDelimitedVec<StructField>>,
291 },
292 /// A tuple struct, e.g., `struct Foo(u32, String);`.
293 TupleStruct {
294 /// The fields enclosed in parentheses `()`.
295 fields: ParenthesisGroupContaining<CommaDelimitedVec<TupleField>>,
296 /// Optional where clauses.
297 clauses: Option<WhereClauses>,
298 /// The trailing semicolon `;`.
299 semi: Semi,
300 },
301 /// A unit struct, e.g., `struct Foo;`.
302 UnitStruct {
303 /// Optional where clauses.
304 clauses: Option<WhereClauses>,
305 /// The trailing semicolon `;`.
306 semi: Semi,
307 },
308 }
309
310 /// Represents a lifetime annotation, like `'a`.
311 pub struct Lifetime {
312 /// The apostrophe `'` starting the lifetime.
313 pub _apostrophe: PunctJoint<'\''>,
314 /// The identifier name of the lifetime (e.g., `a`).
315 pub name: Ident,
316 }
317
318 /// Represents a simple expression, currently only integer literals.
319 /// Used potentially for const generic default values.
320 pub enum Expr {
321 /// An integer literal expression.
322 Integer(LiteralInteger),
323 }
324
325 /// Represents either the `const` or `mut` keyword, often used with pointers.
326 pub enum ConstOrMut {
327 /// The `const` keyword.
328 Const(KConst),
329 /// The `mut` keyword.
330 Mut(KMut),
331 }
332
333 /// Represents a field within a regular struct definition.
334 /// e.g., `pub name: String`.
335 pub struct StructField {
336 /// Attributes applied to the field (e.g., `#[doc = "..."]`).
337 pub attributes: Vec<Attribute>,
338 /// Optional visibility modifier (e.g., `pub`).
339 pub _vis: Option<Vis>,
340 /// The name of the field.
341 pub name: Ident,
342 /// The colon separating the name and type.
343 pub _colon: Colon,
344 /// The type of the field.
345 pub typ: VerbatimUntil<Comma>,
346 }
347
348 /// Represents a field within a tuple struct definition.
349 /// e.g., `pub String`.
350 pub struct TupleField {
351 /// Attributes applied to the field (e.g., `#[doc = "..."]`).
352 pub attributes: Vec<Attribute>,
353 /// Optional visibility modifier (e.g., `pub`).
354 pub vis: Option<Vis>,
355 /// The type of the field.
356 pub typ: VerbatimUntil<Comma>,
357 }
358
359 /// Represents an enum definition.
360 /// e.g., `#[repr(u8)] pub enum MyEnum<T> where T: Clone { Variant1, Variant2(T) }`.
361 pub struct Enum {
362 /// Attributes applied to the enum (e.g., `#[repr(...)]`).
363 pub attributes: Vec<Attribute>,
364 /// Optional visibility modifier (e.g., `pub`, `pub(crate)`, etc.).
365 pub _vis: Option<Vis>,
366 /// The `enum` keyword.
367 pub _kw_enum: KEnum,
368 /// The name of the enum.
369 pub name: Ident,
370 /// Optional generic parameters.
371 pub generics: Option<GenericParams>,
372 /// Optional where clauses.
373 pub clauses: Option<WhereClauses>,
374 /// The enum variants enclosed in braces `{}`.
375 pub body: BraceGroupContaining<CommaDelimitedVec<EnumVariantLike>>,
376 }
377
378 /// Represents a variant of an enum, including the optional discriminant value
379 pub struct EnumVariantLike {
380 /// The actual variant
381 pub variant: EnumVariantData,
382 /// The optional discriminant value
383 pub discriminant: Option<Cons<Eq, VerbatimUntil<Comma>>>
384 }
385
386 /// Represents the different kinds of variants an enum can have.
387 pub enum EnumVariantData {
388 /// A tuple-like variant, e.g., `Variant(u32, String)`.
389 Tuple(TupleVariant),
390 /// A struct-like variant, e.g., `Variant { field1: u32, field2: String }`.
391 Struct(StructEnumVariant),
392 /// A unit-like variant, e.g., `Variant`.
393 Unit(UnitVariant),
394 }
395
396 /// Represents a unit-like enum variant.
397 /// e.g., `MyVariant`.
398 pub struct UnitVariant {
399 /// Attributes applied to the variant.
400 pub attributes: Vec<Attribute>,
401 /// The name of the variant.
402 pub name: Ident,
403 }
404
405 /// Represents a tuple-like enum variant.
406 /// e.g., `MyVariant(u32, String)`.
407 pub struct TupleVariant {
408 /// Attributes applied to the variant.
409 pub attributes: Vec<Attribute>,
410 /// The name of the variant.
411 pub name: Ident,
412 /// The fields enclosed in parentheses `()`.
413 pub fields: ParenthesisGroupContaining<CommaDelimitedVec<TupleField>>,
414 }
415
416 /// Represents a struct-like enum variant.
417 /// e.g., `MyVariant { field1: u32, field2: String }`.
418 pub struct StructEnumVariant {
419 /// Attributes applied to the variant.
420 pub attributes: Vec<Attribute>,
421 /// The name of the variant.
422 pub name: Ident,
423 /// The fields enclosed in braces `{}`.
424 pub fields: BraceGroupContaining<CommaDelimitedVec<StructField>>,
425 }
426
427 /// A lifetime or a tokentree, used to gather lifetimes in type definitions
428 pub enum LifetimeOrTt {
429 /// A lifetime annotation.
430 Lifetime(Lifetime),
431 /// A single token tree.
432 TokenTree(TokenTree),
433 }
434}