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}