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