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