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