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