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