facet_derive_parse/
lib.rs

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