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}