facet_macros_parse/lib.rs
1#![warn(missing_docs)]
2#![doc = include_str!("../README.md")]
3
4/// Parse function signature shape
5#[cfg(feature = "function")]
6pub mod function;
7#[cfg(feature = "function")]
8pub use function::*;
9
10pub use unsynn::*;
11
12keyword! {
13 /// The "pub" keyword.
14 pub KPub = "pub";
15 /// The "struct" keyword.
16 pub KStruct = "struct";
17 /// The "enum" keyword.
18 pub KEnum = "enum";
19 /// The "doc" keyword.
20 pub KDoc = "doc";
21 /// The "repr" keyword.
22 pub KRepr = "repr";
23 /// The "crate" keyword.
24 pub KCrate = "crate";
25 /// The "in" keyword.
26 pub KIn = "in";
27 /// The "const" keyword.
28 pub KConst = "const";
29 /// The "where" keyword.
30 pub KWhere = "where";
31 /// The "mut" keyword.
32 pub KMut = "mut";
33 /// The "facet" keyword.
34 pub KFacet = "facet";
35 /// The "sensitive" keyword.
36 pub KSensitive = "sensitive";
37 /// The "invariants" keyword.
38 pub KInvariants = "invariants";
39 /// The "opaque" keyword.
40 pub KOpaque = "opaque";
41 /// The "deny_unknown_fields" keyword.
42 pub KDenyUnknownFields = "deny_unknown_fields";
43 /// The "default" keyword.
44 pub KDefault = "default";
45 /// The "transparent" keyword.
46 pub KTransparent = "transparent";
47 /// The "rename" keyword.
48 pub KRename = "rename";
49 /// The "rename_all" keyword.
50 pub KRenameAll = "rename_all";
51 /// The "flatten" keyword
52 pub KFlatten = "flatten";
53 /// The "child" keyword
54 pub KChild = "child";
55 /// The "skip_serializing" keyword.
56 pub KSkipSerializing = "skip_serializing";
57 /// The "skip_serializing_if" keyword.
58 pub KSkipSerializingIf = "skip_serializing_if";
59 /// The "type_tag" keyword.
60 pub KTypeTag = "type_tag";
61}
62
63operator! {
64 /// Represents the '=' operator.
65 pub Eq = "=";
66 /// Represents the ';' operator.
67 pub Semi = ";";
68 /// Represents the apostrophe '\'' operator.
69 pub Apostrophe = "'";
70 /// Represents the double semicolon '::' operator.
71 pub DoubleSemicolon = "::";
72}
73
74/// Parses tokens and groups until `C` is found on the current token tree level.
75pub type VerbatimUntil<C> = Many<Cons<Except<C>, AngleTokenTree>>;
76
77/// Represents a module path, consisting of an optional path separator followed by
78/// a path-separator-delimited sequence of identifiers.
79pub type ModPath = Cons<Option<PathSep>, PathSepDelimited<Ident>>;
80
81/// Represents type bounds, consisting of a colon followed by tokens until
82/// a comma, equals sign, or closing angle bracket is encountered.
83pub type Bounds = Cons<Colon, VerbatimUntil<Either<Comma, Eq, Gt>>>;
84
85unsynn! {
86 /// Parses either a `TokenTree` or `<...>` grouping (which is not a [`Group`] as far as proc-macros
87 /// are concerned).
88 #[derive(Clone)]
89 pub struct AngleTokenTree(
90 #[allow(clippy::type_complexity)] // look,
91 pub Either<Cons<Lt, Vec<Cons<Except<Gt>, AngleTokenTree>>, Gt>, TokenTree>,
92 );
93
94 /// Represents an algebraic data type (ADT) declaration, which can be either a struct or enum.
95 pub enum AdtDecl {
96 /// A struct ADT variant.
97 Struct(Struct),
98 /// An enum ADT variant.
99 Enum(Enum),
100 }
101
102 /// Represents visibility modifiers for items.
103 pub enum Vis {
104 /// `pub(in? crate::foo::bar)`/`pub(in? ::foo::bar)`
105 PubIn(Cons<KPub, ParenthesisGroupContaining<Cons<Option<KIn>, ModPath>>>),
106 /// Public visibility, indicated by the "pub" keyword.
107 Pub(KPub),
108 }
109
110 /// Represents an attribute annotation on a field, typically in the form `#[attr]`.
111 pub struct Attribute {
112 /// The pound sign preceding the attribute.
113 pub _pound: Pound,
114 /// The content of the attribute enclosed in square brackets.
115 pub body: BracketGroupContaining<AttributeInner>,
116 }
117
118 /// Represents the inner content of an attribute annotation.
119 pub enum AttributeInner {
120 /// A facet attribute that can contain specialized metadata.
121 Facet(FacetAttr),
122 /// A documentation attribute typically used for generating documentation.
123 Doc(DocInner),
124 /// A representation attribute that specifies how data should be laid out.
125 Repr(ReprInner),
126 /// Any other attribute represented as a sequence of token trees.
127 Any(Vec<TokenTree>),
128 }
129
130 /// Represents a facet attribute that can contain specialized metadata.
131 pub struct FacetAttr {
132 /// The keyword for the facet attribute.
133 pub _facet: KFacet,
134 /// The inner content of the facet attribute.
135 pub inner: ParenthesisGroupContaining<CommaDelimitedVec<FacetInner>>,
136 }
137
138 /// Represents the inner content of a facet attribute.
139 pub enum FacetInner {
140 /// A sensitive attribute that specifies sensitivity information.
141 Sensitive(KSensitive),
142 /// An invariants attribute that specifies invariants for the type.
143 Invariants(InvariantInner),
144 /// An opaque attribute that specifies opaque information.
145 Opaque(KOpaque),
146 /// A deny_unknown_fields attribute that specifies whether unknown fields are allowed.
147 DenyUnknownFields(KDenyUnknownFields),
148 /// A default attribute with an explicit value (#[facet(default = "myfunc")])
149 DefaultEquals(DefaultEqualsInner),
150 /// A default attribute with no explicit value (#[facet(default)])
151 Default(KDefault),
152 /// A transparent attribute for containers
153 Transparent(KTransparent),
154 /// A rename_all attribute that specifies a case conversion for all fields/variants (#[facet(rename_all = "camelCase")])
155 RenameAll(RenameAllInner),
156 /// A rename attribute that specifies a custom name for a field/variant (#[facet(rename = "custom_name")])
157 Rename(RenameInner),
158 /// A flatten attribute that marks a field to be flattened into the parent structure
159 Flatten(FlattenInner),
160 /// A child attribute that marks a field as a child node
161 Child(ChildInner),
162 /// A skip_serializing attribute that specifies whether a field should be skipped during serialization.
163 SkipSerializing(SkipSerializingInner),
164 /// A skip_serializing_if attribute that specifies a condition for skipping serialization.
165 SkipSerializingIf(SkipSerializingIfInner),
166 /// A type_tag attribute that specifies the identifying tag for self describing formats
167 TypeTag(TypeTagInner),
168 /// Any other attribute represented as a sequence of token trees.
169 Arbitrary(VerbatimUntil<Comma>),
170 }
171
172 /// Inner value for #[facet(flatten)]
173 pub struct FlattenInner {
174 /// The "flatten" keyword.
175 pub _kw_flatten: KFlatten,
176 }
177
178 /// Inner value for #[facet(child)]
179 pub struct ChildInner {
180 /// The "child" keyword.
181 pub _kw_child: KChild,
182 }
183
184 /// Inner value for #[facet(skip_serializing)]
185 pub struct SkipSerializingInner {
186 /// The "skip_serializing" keyword.
187 pub _kw_skip_serializing: KSkipSerializing,
188 }
189
190 /// Inner value for #[facet(skip_serializing_if = ...)]
191 pub struct SkipSerializingIfInner {
192 /// The "skip_serializing_if" keyword.
193 pub _kw_skip_serializing_if: KSkipSerializingIf,
194 /// The equals sign '='.
195 pub _eq: Eq,
196 /// The conditional expression as verbatim until comma.
197 pub expr: VerbatimUntil<Comma>,
198 }
199
200 /// Inner value for #[facet(type_tag = ...)]
201 pub struct TypeTagInner {
202 /// The "type_tag" keyword.
203 pub _kw_type_tag: KTypeTag,
204 /// The equals sign '='.
205 pub _eq: Eq,
206 /// The value assigned, as a literal string.
207 pub expr: LiteralString,
208 }
209
210 /// Inner value for #[facet(default = ...)]
211 pub struct DefaultEqualsInner {
212 /// The "default" keyword.
213 pub _kw_default: KDefault,
214 /// The equals sign '='.
215 pub _eq: Eq,
216 /// The value assigned, as verbatim until comma.
217 pub expr: VerbatimUntil<Comma>,
218 }
219
220 /// Inner value for #[facet(rename = ...)]
221 pub struct RenameInner {
222 /// The "rename" keyword.
223 pub _kw_rename: KRename,
224 /// The equals sign '='.
225 pub _eq: Eq,
226 /// The value assigned, as a literal string.
227 pub value: LiteralString,
228 }
229
230 /// Inner value for #[facet(rename_all = ...)]
231 pub struct RenameAllInner {
232 /// The "rename_all" keyword.
233 pub _kw_rename_all: KRenameAll,
234 /// The equals sign '='.
235 pub _eq: Eq,
236 /// The value assigned, as a literal string.
237 pub value: LiteralString,
238 }
239
240 /// Represents invariants for a type.
241 pub struct InvariantInner {
242 /// The "invariants" keyword.
243 pub _kw_invariants: KInvariants,
244 /// The equality operator.
245 pub _eq: Eq,
246 /// The invariant value
247 pub expr: VerbatimUntil<Comma>,
248 }
249
250 /// Represents documentation for an item.
251 pub struct DocInner {
252 /// The "doc" keyword.
253 pub _kw_doc: KDoc,
254 /// The equality operator.
255 pub _eq: Eq,
256 /// The documentation content as a literal string.
257 pub value: LiteralString,
258 }
259
260 /// Represents the inner content of a `repr` attribute, typically used for specifying
261 /// memory layout or representation hints.
262 pub struct ReprInner {
263 /// The "repr" keyword.
264 pub _kw_repr: KRepr,
265 /// The representation attributes enclosed in parentheses.
266 pub attr: ParenthesisGroupContaining<CommaDelimitedVec<Ident>>,
267 }
268
269 /// Represents a struct definition.
270 pub struct Struct {
271 /// Attributes applied to the struct.
272 pub attributes: Vec<Attribute>,
273 /// The visibility modifier of the struct (e.g., `pub`).
274 pub _vis: Option<Vis>,
275 /// The "struct" keyword.
276 pub _kw_struct: KStruct,
277 /// The name of the struct.
278 pub name: Ident,
279 /// Generic parameters for the struct, if any.
280 pub generics: Option<GenericParams>,
281 /// The variant of struct (unit, tuple, or regular struct with named fields).
282 pub kind: StructKind,
283 }
284
285 /// Represents the generic parameters of a struct or enum definition, enclosed in angle brackets.
286 /// e.g., `<'a, T: Trait, const N: usize>`.
287 pub struct GenericParams {
288 /// The opening angle bracket `<`.
289 pub _lt: Lt,
290 /// The comma-delimited list of generic parameters.
291 pub params: CommaDelimitedVec<GenericParam>,
292 /// The closing angle bracket `>`.
293 pub _gt: Gt,
294 }
295
296 /// Represents a single generic parameter within a `GenericParams` list.
297 pub enum GenericParam {
298 /// A lifetime parameter, e.g., `'a` or `'a: 'b + 'c`.
299 Lifetime {
300 /// The lifetime identifier (e.g., `'a`).
301 name: Lifetime,
302 /// Optional lifetime bounds (e.g., `: 'b + 'c`).
303 bounds: Option<Cons<Colon, VerbatimUntil<Either<Comma, Gt>>>>,
304 },
305 /// A const generic parameter, e.g., `const N: usize = 10`.
306 Const {
307 /// The `const` keyword.
308 _const: KConst,
309 /// The name of the const parameter (e.g., `N`).
310 name: Ident,
311 /// The colon separating the name and type.
312 _colon: Colon,
313 /// The type of the const parameter (e.g., `usize`).
314 typ: VerbatimUntil<Either<Comma, Gt, Eq>>,
315 /// An optional default value (e.g., `= 10`).
316 default: Option<Cons<Eq, VerbatimUntil<Either<Comma, Gt>>>>,
317 },
318 /// A type parameter, e.g., `T: Trait = DefaultType`.
319 Type {
320 /// The name of the type parameter (e.g., `T`).
321 name: Ident,
322 /// Optional type bounds (e.g., `: Trait`).
323 bounds: Option<Bounds>,
324 /// An optional default type (e.g., `= DefaultType`).
325 default: Option<Cons<Eq, VerbatimUntil<Either<Comma, Gt>>>>,
326 },
327 }
328
329 /// Represents a `where` clause attached to a definition.
330 /// e.g., `where T: Trait, 'a: 'b`.
331 #[derive(Clone)]
332 pub struct WhereClauses {
333 /// The `where` keyword.
334 pub _kw_where: KWhere,
335 /// The comma-delimited list of where clause predicates.
336 pub clauses: CommaDelimitedVec<WhereClause>,
337 }
338
339 /// Represents a single predicate within a `where` clause.
340 /// e.g., `T: Trait` or `'a: 'b`.
341 #[derive(Clone)]
342 pub struct WhereClause {
343 // FIXME: This likely breaks for absolute `::` paths
344 /// The type or lifetime being constrained (e.g., `T` or `'a`).
345 pub _pred: VerbatimUntil<Colon>,
346 /// The colon separating the constrained item and its bounds.
347 pub _colon: Colon,
348 /// The bounds applied to the type or lifetime (e.g., `Trait` or `'b`).
349 pub bounds: VerbatimUntil<Either<Comma, Semicolon, BraceGroup>>,
350 }
351
352 /// Represents the kind of a struct definition.
353 pub enum StructKind {
354 /// A regular struct with named fields, e.g., `struct Foo { bar: u32 }`.
355 Struct {
356 /// Optional where clauses.
357 clauses: Option<WhereClauses>,
358 /// The fields enclosed in braces `{}`.
359 fields: BraceGroupContaining<CommaDelimitedVec<StructField>>,
360 },
361 /// A tuple struct, e.g., `struct Foo(u32, String);`.
362 TupleStruct {
363 /// The fields enclosed in parentheses `()`.
364 fields: ParenthesisGroupContaining<CommaDelimitedVec<TupleField>>,
365 /// Optional where clauses.
366 clauses: Option<WhereClauses>,
367 /// The trailing semicolon `;`.
368 semi: Semi,
369 },
370 /// A unit struct, e.g., `struct Foo;`.
371 UnitStruct {
372 /// Optional where clauses.
373 clauses: Option<WhereClauses>,
374 /// The trailing semicolon `;`.
375 semi: Semi,
376 },
377 }
378
379 /// Represents a lifetime annotation, like `'a`.
380 pub struct Lifetime {
381 /// The apostrophe `'` starting the lifetime.
382 pub _apostrophe: PunctJoint<'\''>,
383 /// The identifier name of the lifetime (e.g., `a`).
384 pub name: Ident,
385 }
386
387 /// Represents a simple expression, currently only integer literals.
388 /// Used potentially for const generic default values.
389 pub enum Expr {
390 /// An integer literal expression.
391 Integer(LiteralInteger),
392 }
393
394 /// Represents either the `const` or `mut` keyword, often used with pointers.
395 pub enum ConstOrMut {
396 /// The `const` keyword.
397 Const(KConst),
398 /// The `mut` keyword.
399 Mut(KMut),
400 }
401
402 /// Represents a field within a regular struct definition.
403 /// e.g., `pub name: String`.
404 pub struct StructField {
405 /// Attributes applied to the field (e.g., `#[doc = "..."]`).
406 pub attributes: Vec<Attribute>,
407 /// Optional visibility modifier (e.g., `pub`).
408 pub _vis: Option<Vis>,
409 /// The name of the field.
410 pub name: Ident,
411 /// The colon separating the name and type.
412 pub _colon: Colon,
413 /// The type of the field.
414 pub typ: VerbatimUntil<Comma>,
415 }
416
417 /// Represents a field within a tuple struct definition.
418 /// e.g., `pub String`.
419 pub struct TupleField {
420 /// Attributes applied to the field (e.g., `#[doc = "..."]`).
421 pub attributes: Vec<Attribute>,
422 /// Optional visibility modifier (e.g., `pub`).
423 pub vis: Option<Vis>,
424 /// The type of the field.
425 pub typ: VerbatimUntil<Comma>,
426 }
427
428 /// Represents an enum definition.
429 /// e.g., `#[repr(u8)] pub enum MyEnum<T> where T: Clone { Variant1, Variant2(T) }`.
430 pub struct Enum {
431 /// Attributes applied to the enum (e.g., `#[repr(...)]`).
432 pub attributes: Vec<Attribute>,
433 /// Optional visibility modifier (e.g., `pub`, `pub(crate)`, etc.).
434 pub _vis: Option<Vis>,
435 /// The `enum` keyword.
436 pub _kw_enum: KEnum,
437 /// The name of the enum.
438 pub name: Ident,
439 /// Optional generic parameters.
440 pub generics: Option<GenericParams>,
441 /// Optional where clauses.
442 pub clauses: Option<WhereClauses>,
443 /// The enum variants enclosed in braces `{}`.
444 pub body: BraceGroupContaining<CommaDelimitedVec<EnumVariantLike>>,
445 }
446
447 /// Represents a variant of an enum, including the optional discriminant value
448 pub struct EnumVariantLike {
449 /// The actual variant
450 pub variant: EnumVariantData,
451 /// The optional discriminant value
452 pub discriminant: Option<Cons<Eq, VerbatimUntil<Comma>>>
453 }
454
455 /// Represents the different kinds of variants an enum can have.
456 pub enum EnumVariantData {
457 /// A tuple-like variant, e.g., `Variant(u32, String)`.
458 Tuple(TupleVariant),
459 /// A struct-like variant, e.g., `Variant { field1: u32, field2: String }`.
460 Struct(StructEnumVariant),
461 /// A unit-like variant, e.g., `Variant`.
462 Unit(UnitVariant),
463 }
464
465 /// Represents a unit-like enum variant.
466 /// e.g., `MyVariant`.
467 pub struct UnitVariant {
468 /// Attributes applied to the variant.
469 pub attributes: Vec<Attribute>,
470 /// The name of the variant.
471 pub name: Ident,
472 }
473
474 /// Represents a tuple-like enum variant.
475 /// e.g., `MyVariant(u32, String)`.
476 pub struct TupleVariant {
477 /// Attributes applied to the variant.
478 pub attributes: Vec<Attribute>,
479 /// The name of the variant.
480 pub name: Ident,
481 /// The fields enclosed in parentheses `()`.
482 pub fields: ParenthesisGroupContaining<CommaDelimitedVec<TupleField>>,
483 }
484
485 /// Represents a struct-like enum variant.
486 /// e.g., `MyVariant { field1: u32, field2: String }`.
487 pub struct StructEnumVariant {
488 /// Attributes applied to the variant.
489 pub attributes: Vec<Attribute>,
490 /// The name of the variant.
491 pub name: Ident,
492 /// The fields enclosed in braces `{}`.
493 pub fields: BraceGroupContaining<CommaDelimitedVec<StructField>>,
494 }
495
496 /// A lifetime or a tokentree, used to gather lifetimes in type definitions
497 pub enum LifetimeOrTt {
498 /// A lifetime annotation.
499 Lifetime(Lifetime),
500 /// A single token tree.
501 TokenTree(TokenTree),
502 }
503}
504
505impl core::fmt::Display for AngleTokenTree {
506 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
507 match &self.0 {
508 Either::First(it) => {
509 write!(f, "<")?;
510 for it in it.second.iter() {
511 write!(f, "{}", it.second)?;
512 }
513 write!(f, ">")?;
514 }
515 Either::Second(it) => write!(f, "{}", it)?,
516 Either::Third(Invalid) => unreachable!(),
517 Either::Fourth(Invalid) => unreachable!(),
518 };
519 Ok(())
520 }
521}
522
523/// Display the verbatim tokens until the given token.
524pub struct VerbatimDisplay<'a, C>(pub &'a VerbatimUntil<C>);
525
526impl<C> core::fmt::Display for VerbatimDisplay<'_, C> {
527 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
528 for tt in self.0.0.iter() {
529 write!(f, "{}", tt.value.second)?;
530 }
531 Ok(())
532 }
533}
534
535impl core::fmt::Display for ConstOrMut {
536 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
537 match self {
538 ConstOrMut::Const(_) => write!(f, "const"),
539 ConstOrMut::Mut(_) => write!(f, "mut"),
540 }
541 }
542}
543
544impl core::fmt::Display for Lifetime {
545 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
546 write!(f, "'{}", self.name)
547 }
548}
549
550impl core::fmt::Display for WhereClauses {
551 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
552 write!(f, "where ")?;
553 for clause in self.clauses.0.iter() {
554 write!(f, "{},", clause.value)?;
555 }
556 Ok(())
557 }
558}
559
560impl core::fmt::Display for WhereClause {
561 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
562 write!(
563 f,
564 "{}: {}",
565 VerbatimDisplay(&self._pred),
566 VerbatimDisplay(&self.bounds)
567 )
568 }
569}
570
571impl core::fmt::Display for Expr {
572 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
573 match self {
574 Expr::Integer(int) => write!(f, "{}", int.value()),
575 }
576 }
577}
578
579impl Struct {
580 /// Returns an iterator over the `FacetInner` content of `#[facet(...)]` attributes
581 /// applied to this struct.
582 pub fn facet_attributes(&self) -> impl Iterator<Item = &FacetInner> {
583 self.attributes
584 .iter()
585 .filter_map(|attr| match &attr.body.content {
586 AttributeInner::Facet(f) => Some(&f.inner.content.0),
587 _ => None,
588 })
589 .flatten()
590 .map(|d| &d.value)
591 }
592
593 /// Returns `true` if the struct is marked `#[facet(transparent)]`.
594 pub fn is_transparent(&self) -> bool {
595 self.facet_attributes()
596 .any(|inner| matches!(inner, FacetInner::Transparent(_)))
597 }
598}