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}