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