glsl_lang_types/
ast.rs

1//! GLSL abstract syntax tree and grammar.
2//!
3//! This module exports all the grammar syntax that defines GLSL. You’ll be handling ASTs
4//! representing your GLSL source.
5//!
6//! The most external form of a GLSL parsed AST is [`TranslationUnit`] (a shader). Some parts of the
7//! tree are *boxed*. This is due to two facts:
8//!
9//! - Recursion is used, hence we need a way to give our types a static size.
10//! - Because of some very deep variants, runtime size would explode if no indirection weren’t
11//!   in place.
12//!
13//! The types are commented so feel free to inspect each of theme. As a starter, you should read
14//! the documentation of [`Expr`], [`FunctionDefinition`], [`Statement`] and [`TranslationUnit`].
15//!
16//! [`Statement`]: crate::ast::Statement
17//! [`TranslationUnit`]: crate::ast::TranslationUnit
18//! [`Expr`]: crate::ast::Expr
19//! [`FunctionDefinition`]: crate::ast::FunctionDefinition
20
21use std::{fmt, iter::FromIterator};
22
23#[cfg(feature = "serde")]
24use rserde::{Deserialize, Serialize};
25
26pub use lang_util::{
27    node::{Node, NodeDisplay},
28    position::NodeSpan,
29    FileId, NodeContent, NodeContentDisplay, SmolStr, TextRange, TextSize,
30};
31
32macro_rules! impl_node_content {
33    (
34        $(#[$m:meta])* $v:vis type $t:ident = Node<$tdata:ident>;
35    ) => {
36        impl NodeContent for $tdata {}
37
38        $(#[$m])* $v type $t = Node<$tdata>;
39
40        impl From<Node<$tdata>> for $tdata {
41            fn from(node: Node<$tdata>) -> Self {
42                node.content
43            }
44        }
45    };
46}
47
48/// A generic identifier.
49#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Hash, NodeContentDisplay)]
50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
51#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
52#[lang_util(display(leaf))]
53pub struct IdentifierData(#[lang_util(display(extra))] pub SmolStr);
54
55impl_node_content! {
56    /// Type alias for `Node<IdentifierData>`.
57    pub type Identifier = Node<IdentifierData>;
58}
59
60impl IdentifierData {
61    /// Parses this identifier as a glsl-lang-quote Rust identifier
62    ///
63    /// # Returns
64    ///
65    /// `None` if this identifier is not a Rust identifier, otherwise returns the parsed
66    /// identifier.
67    pub fn as_rs_ident(&self) -> Option<&str> {
68        if self.0.starts_with('#') & self.0.ends_with(')') {
69            // Remove #\s* and )
70            let s = self.0[1..self.0.len() - 1].trim();
71            // Remove ( and whitespace
72            Some(s[1..].trim())
73        } else {
74            None
75        }
76    }
77
78    /// Returns this identifier as a string slice
79    pub fn as_str(&self) -> &str {
80        self.0.as_str()
81    }
82}
83
84impl From<&str> for IdentifierData {
85    fn from(ident: &str) -> Self {
86        Self(ident.into())
87    }
88}
89
90impl fmt::Display for IdentifierData {
91    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
92        self.0.fmt(f)
93    }
94}
95
96/// Any type name.
97#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Hash, NodeContentDisplay)]
98#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
99#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
100#[lang_util(display(leaf))]
101pub struct TypeNameData(pub SmolStr);
102
103impl_node_content! {
104    /// Type alias for `Node<TypeNameData>`.
105    pub type TypeName = Node<TypeNameData>;
106}
107
108impl TypeNameData {
109    /// Return this type name as a string slice
110    pub fn as_str(&self) -> &str {
111        self.0.as_str()
112    }
113}
114
115impl From<IdentifierData> for TypeNameData {
116    fn from(ident: IdentifierData) -> Self {
117        Self(ident.0)
118    }
119}
120
121impl From<&str> for TypeNameData {
122    fn from(ident: &str) -> Self {
123        Self(ident.into())
124    }
125}
126
127impl fmt::Display for TypeNameData {
128    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
129        self.0.fmt(f)
130    }
131}
132
133/// A path literal.
134#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
135#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
136#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
137pub enum PathData {
138    /// Specified with angle brackets.
139    Absolute(String),
140    /// Specified with double quotes.
141    Relative(String),
142}
143
144impl_node_content! {
145    /// Type alias for `Node<PathData>`.
146    pub type Path = Node<PathData>;
147}
148
149/// Type specifier (non-array).
150#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
151#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
152#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
153pub enum TypeSpecifierNonArrayData {
154    /// `void` type specifier
155    #[lang_util(display(extra = "void"))]
156    Void,
157    /// `bool` type specifier
158    #[lang_util(display(extra = "bool"))]
159    Bool,
160    /// `int` type specifier
161    #[lang_util(display(extra = "int"))]
162    Int,
163    /// `uint` type specifier
164    #[lang_util(display(extra = "uint"))]
165    UInt,
166    /// `float` type specifier
167    #[lang_util(display(extra = "float"))]
168    Float,
169    /// `double` type specifier
170    #[lang_util(display(extra = "double"))]
171    Double,
172    /// `vec2` type specifier
173    #[lang_util(display(extra = "vec2"))]
174    Vec2,
175    /// `vec3` type specifier
176    #[lang_util(display(extra = "vec3"))]
177    Vec3,
178    /// `vec4` type specifier
179    #[lang_util(display(extra = "vec4"))]
180    Vec4,
181    /// `dvec2` type specifier
182    #[lang_util(display(extra = "dvec2"))]
183    DVec2,
184    /// `dvec3` type specifier
185    #[lang_util(display(extra = "dvec3"))]
186    DVec3,
187    /// `dvec4` type specifier
188    #[lang_util(display(extra = "dvec4"))]
189    DVec4,
190    /// `bvec2` type specifier
191    #[lang_util(display(extra = "bvec2"))]
192    BVec2,
193    /// `bvec3` type specifier
194    #[lang_util(display(extra = "bvec3"))]
195    BVec3,
196    /// `bvec4` type specifier
197    #[lang_util(display(extra = "bvec4"))]
198    BVec4,
199    /// `ivec2` type specifier
200    #[lang_util(display(extra = "ivec2"))]
201    IVec2,
202    /// `ivec3` type specifier
203    #[lang_util(display(extra = "ivec3"))]
204    IVec3,
205    /// `ivec4` type specifier
206    #[lang_util(display(extra = "ivec4"))]
207    IVec4,
208    /// `uvec2` type specifier
209    #[lang_util(display(extra = "uvec2"))]
210    UVec2,
211    /// `uvec3` type specifier
212    #[lang_util(display(extra = "uvec3"))]
213    UVec3,
214    /// `uvec4` type specifier
215    #[lang_util(display(extra = "uvec4"))]
216    UVec4,
217    /// `mat2` type specifier
218    #[lang_util(display(extra = "mat2"))]
219    Mat2,
220    /// `mat3` type specifier
221    #[lang_util(display(extra = "mat3"))]
222    Mat3,
223    /// `mat4` type specifier
224    #[lang_util(display(extra = "mat4"))]
225    Mat4,
226    /// `mat2x2` type specifier
227    #[lang_util(display(extra = "mat2x2"))]
228    Mat22,
229    /// `mat2x3` type specifier
230    #[lang_util(display(extra = "mat2x3"))]
231    Mat23,
232    /// `mat2x4` type specifier
233    #[lang_util(display(extra = "mat2x4"))]
234    Mat24,
235    /// `mat3x2` type specifier
236    #[lang_util(display(extra = "mat3x2"))]
237    Mat32,
238    /// `mat3x3` type specifier
239    #[lang_util(display(extra = "mat3x3"))]
240    Mat33,
241    /// `mat3x4` type specifier
242    #[lang_util(display(extra = "mat3x4"))]
243    Mat34,
244    /// `mat4x2` type specifier
245    #[lang_util(display(extra = "mat4x2"))]
246    Mat42,
247    /// `mat4x3` type specifier
248    #[lang_util(display(extra = "mat4x3"))]
249    Mat43,
250    /// `mat4x4` type specifier
251    #[lang_util(display(extra = "mat4x4"))]
252    Mat44,
253    /// `dmat2` type specifier
254    #[lang_util(display(extra = "dmat2"))]
255    DMat2,
256    /// `dmat3` type specifier
257    #[lang_util(display(extra = "dmat3"))]
258    DMat3,
259    /// `dmat4` type specifier
260    #[lang_util(display(extra = "dmat4"))]
261    DMat4,
262    /// `dmat2x2` type specifier
263    #[lang_util(display(extra = "dmat2x2"))]
264    DMat22,
265    /// `dmat2x3` type specifier
266    #[lang_util(display(extra = "dmat2x3"))]
267    DMat23,
268    /// `dmat2x4` type specifier
269    #[lang_util(display(extra = "dmat2x4"))]
270    DMat24,
271    /// `dmat3x2` type specifier
272    #[lang_util(display(extra = "dmat3x2"))]
273    DMat32,
274    /// `dmat3x3` type specifier
275    #[lang_util(display(extra = "dmat3x3"))]
276    DMat33,
277    /// `dmat3x4` type specifier
278    #[lang_util(display(extra = "dmat3x4"))]
279    DMat34,
280    /// `dmat4x2` type specifier
281    #[lang_util(display(extra = "dmat4x2"))]
282    DMat42,
283    /// `dmat4x3` type specifier
284    #[lang_util(display(extra = "dmat4x3"))]
285    DMat43,
286    /// `dmat4x4` type specifier
287    #[lang_util(display(extra = "dmat4x4"))]
288    DMat44,
289    // floating point opaque types
290    /// `sampler1D` type specifier
291    #[lang_util(display(extra = "sampler1D"))]
292    Sampler1D,
293    /// `image1D` type specifier
294    #[lang_util(display(extra = "image1D"))]
295    Image1D,
296    /// `sampler2D` type specifier
297    #[lang_util(display(extra = "sampler2D"))]
298    Sampler2D,
299    /// `image2D` type specifier
300    #[lang_util(display(extra = "image2D"))]
301    Image2D,
302    /// `sampler3D` type specifier
303    #[lang_util(display(extra = "sampler3D"))]
304    Sampler3D,
305    /// `image3D` type specifier
306    #[lang_util(display(extra = "image3D"))]
307    Image3D,
308    /// `samplerCube` type specifier
309    #[lang_util(display(extra = "samplerCube"))]
310    SamplerCube,
311    /// `imageCube` type specifier
312    #[lang_util(display(extra = "imageCube"))]
313    ImageCube,
314    /// `sampler2DRect` type specifier
315    #[lang_util(display(extra = "sampler2DRect"))]
316    Sampler2DRect,
317    /// `image2DRect` type specifier
318    #[lang_util(display(extra = "image2DRect"))]
319    Image2DRect,
320    /// `sampler1DArray` type specifier
321    #[lang_util(display(extra = "sampler1DArray"))]
322    Sampler1DArray,
323    /// `image1DArray` type specifier
324    #[lang_util(display(extra = "image1DArray"))]
325    Image1DArray,
326    /// `sampler2DArray` type specifier
327    #[lang_util(display(extra = "sampler2DArray"))]
328    Sampler2DArray,
329    /// `image2DArray` type specifier
330    #[lang_util(display(extra = "image2DArray"))]
331    Image2DArray,
332    /// `samplerBuffer` type specifier
333    #[lang_util(display(extra = "samplerBuffer"))]
334    SamplerBuffer,
335    /// `imageBuffer` type specifier
336    #[lang_util(display(extra = "imageBuffer"))]
337    ImageBuffer,
338    /// `sampler2DMS` type specifier
339    #[lang_util(display(extra = "sampler2DMS"))]
340    Sampler2DMs,
341    /// `image2DMS` type specifier
342    #[lang_util(display(extra = "image2DMS"))]
343    Image2DMs,
344    /// `sampler2DMSArray` type specifier
345    #[lang_util(display(extra = "sampler2DMSArray"))]
346    Sampler2DMsArray,
347    /// `image2DMSArray` type specifier
348    #[lang_util(display(extra = "image2DMSArray"))]
349    Image2DMsArray,
350    /// `samplerCubeArray` type specifier
351    #[lang_util(display(extra = "samplerCubeArray"))]
352    SamplerCubeArray,
353    /// `imageCubeArray` type specifier
354    #[lang_util(display(extra = "imageCubeArray"))]
355    ImageCubeArray,
356    /// `sampler1DShadow` type specifier
357    #[lang_util(display(extra = "sampler1DShadow"))]
358    Sampler1DShadow,
359    /// `sampler2DShadow` type specifier
360    #[lang_util(display(extra = "sampler2DShadow"))]
361    Sampler2DShadow,
362    /// `sampler2DRectShadow` type specifier
363    #[lang_util(display(extra = "sampler2DRectShadow"))]
364    Sampler2DRectShadow,
365    /// `sampler1DArrayShadow` type specifier
366    #[lang_util(display(extra = "sampler1DArrayShadow"))]
367    Sampler1DArrayShadow,
368    /// `sampler2DArrayShadow` type specifier
369    #[lang_util(display(extra = "sampler2DArrayShadow"))]
370    Sampler2DArrayShadow,
371    /// `samplerCubeShadow` type specifier
372    #[lang_util(display(extra = "samplerCubeShadow"))]
373    SamplerCubeShadow,
374    /// `samplerCubeArrayShadow` type specifier
375    #[lang_util(display(extra = "samplerCubeArrayShadow"))]
376    SamplerCubeArrayShadow,
377    // signed integer opaque types
378    /// `isampler1D` type specifier
379    #[lang_util(display(extra = "isampler1D"))]
380    ISampler1D,
381    /// `iimage1D` type specifier
382    #[lang_util(display(extra = "iimage1D"))]
383    IImage1D,
384    /// `isampler2D` type specifier
385    #[lang_util(display(extra = "isampler2D"))]
386    ISampler2D,
387    /// `iimage2D` type specifier
388    #[lang_util(display(extra = "iimage2D"))]
389    IImage2D,
390    /// `isampler3D` type specifier
391    #[lang_util(display(extra = "isampler3D"))]
392    ISampler3D,
393    /// `iimage3D` type specifier
394    #[lang_util(display(extra = "iimage3D"))]
395    IImage3D,
396    /// `isamplerCube` type specifier
397    #[lang_util(display(extra = "isamplerCube"))]
398    ISamplerCube,
399    /// `iimageCube` type specifier
400    #[lang_util(display(extra = "iimageCube"))]
401    IImageCube,
402    /// `isampler2DRect` type specifier
403    #[lang_util(display(extra = "isampler2DRect"))]
404    ISampler2DRect,
405    /// `iimage2DRect` type specifier
406    #[lang_util(display(extra = "iimage2DRect"))]
407    IImage2DRect,
408    /// `isampler1DArray` type specifier
409    #[lang_util(display(extra = "isampler1DArray"))]
410    ISampler1DArray,
411    /// `iimage1DArray` type specifier
412    #[lang_util(display(extra = "iimage1DArray"))]
413    IImage1DArray,
414    /// `isampler2DArray` type specifier
415    #[lang_util(display(extra = "isampler2DArray"))]
416    ISampler2DArray,
417    /// `iimage2DArray` type specifier
418    #[lang_util(display(extra = "iimage2DArray"))]
419    IImage2DArray,
420    /// `isamplerBuffer` type specifier
421    #[lang_util(display(extra = "isamplerBuffer"))]
422    ISamplerBuffer,
423    /// `iimageBuffer` type specifier
424    #[lang_util(display(extra = "iimageBuffer"))]
425    IImageBuffer,
426    /// `isampler2DMS` type specifier
427    #[lang_util(display(extra = "isampler2DMS"))]
428    ISampler2DMs,
429    /// `iimage2DMS` type specifier
430    #[lang_util(display(extra = "iimage2DMS"))]
431    IImage2DMs,
432    /// `isampler2DMSArray` type specifier
433    #[lang_util(display(extra = "isampler2DMSArray"))]
434    ISampler2DMsArray,
435    /// `iimage2DMSArray` type specifier
436    #[lang_util(display(extra = "iimage2DMSArray"))]
437    IImage2DMsArray,
438    /// `isamplerCubeArray` type specifier
439    #[lang_util(display(extra = "isamplerCubeArray"))]
440    ISamplerCubeArray,
441    /// `iimageCubeArray` type specifier
442    #[lang_util(display(extra = "iimageCubeArray"))]
443    IImageCubeArray,
444    // unsigned integer opaque types
445    /// `atomic_uint` type specifier
446    #[lang_util(display(extra = "atomic_uint"))]
447    AtomicUInt,
448    /// `usampler1D` type specifier
449    #[lang_util(display(extra = "usampler1D"))]
450    USampler1D,
451    /// `uimage1D` type specifier
452    #[lang_util(display(extra = "uimage1D"))]
453    UImage1D,
454    /// `usampler2D` type specifier
455    #[lang_util(display(extra = "usampler2D"))]
456    USampler2D,
457    /// `uimage2D` type specifier
458    #[lang_util(display(extra = "uimage2D"))]
459    UImage2D,
460    /// `usampler3D` type specifier
461    #[lang_util(display(extra = "usampler3D"))]
462    USampler3D,
463    /// `uimage3D` type specifier
464    #[lang_util(display(extra = "uimage3D"))]
465    UImage3D,
466    /// `usamplerCube` type specifier
467    #[lang_util(display(extra = "usamplerCube"))]
468    USamplerCube,
469    /// `uimageCube` type specifier
470    #[lang_util(display(extra = "uimageCube"))]
471    UImageCube,
472    /// `usampler2DRect` type specifier
473    #[lang_util(display(extra = "usampler2DRect"))]
474    USampler2DRect,
475    /// `uimage2DRect` type specifier
476    #[lang_util(display(extra = "uimage2DRect"))]
477    UImage2DRect,
478    /// `usampler1DArray` type specifier
479    #[lang_util(display(extra = "usampler1DArray"))]
480    USampler1DArray,
481    /// `uimage1DArray` type specifier
482    #[lang_util(display(extra = "uimage1DArray"))]
483    UImage1DArray,
484    /// `usampler2DArray` type specifier
485    #[lang_util(display(extra = "usampler2DArray"))]
486    USampler2DArray,
487    /// `uimage2DArray` type specifier
488    #[lang_util(display(extra = "uimage2DArray"))]
489    UImage2DArray,
490    /// `usamplerBuffer` type specifier
491    #[lang_util(display(extra = "usamplerBuffer"))]
492    USamplerBuffer,
493    /// `uimageBuffer` type specifier
494    #[lang_util(display(extra = "uimageBuffer"))]
495    UImageBuffer,
496    /// `usampler2DMS` type specifier
497    #[lang_util(display(extra = "usampler2DMS"))]
498    USampler2DMs,
499    /// `uimage2DMS` type specifier
500    #[lang_util(display(extra = "uimage2DMS"))]
501    UImage2DMs,
502    /// `usampler2DMSArray` type specifier
503    #[lang_util(display(extra = "usampler2DMSArray"))]
504    USampler2DMsArray,
505    /// `uimage2DMSArray` type specifier
506    #[lang_util(display(extra = "uimage2DMSArray"))]
507    UImage2DMsArray,
508    /// `usamplerCubeArray` type specifier
509    #[lang_util(display(extra = "usamplerCubeArray"))]
510    USamplerCubeArray,
511    /// `uimageCubeArray` type specifier
512    #[lang_util(display(extra = "uimageCubeArray"))]
513    UImageCubeArray,
514
515    // GL_KHR_vulkan_glsl types
516    /// `texture1D` type specifier
517    #[lang_util(display(extra = "texture1D"))]
518    Texture1D,
519    /// `texture2D` type specifier
520    #[lang_util(display(extra = "texture2D"))]
521    Texture2D,
522    /// `texture3D` type specifier
523    #[lang_util(display(extra = "texture3D"))]
524    Texture3D,
525    /// `textureCube` type specifier
526    #[lang_util(display(extra = "textureCube"))]
527    TextureCube,
528    /// `texture2DRect` type specifier
529    #[lang_util(display(extra = "texture2DRect"))]
530    Texture2DRect,
531    /// `texture1DArray` type specifier
532    #[lang_util(display(extra = "texture1DArray"))]
533    Texture1DArray,
534    /// `texture2DArray` type specifier
535    #[lang_util(display(extra = "texture2DArray"))]
536    Texture2DArray,
537    /// `textureBuffer` type specifier
538    #[lang_util(display(extra = "textureBuffer"))]
539    TextureBuffer,
540    /// `texture2DMs` type specifier
541    #[lang_util(display(extra = "texture2DMS"))]
542    Texture2DMs,
543    /// `texture2DMsArray` type specifier
544    #[lang_util(display(extra = "texture2DMSArray"))]
545    Texture2DMsArray,
546    /// `textureCubeArray` type specifier
547    #[lang_util(display(extra = "textureCubeArray"))]
548    TextureCubeArray,
549    /// `itexture1D` type specifier
550    #[lang_util(display(extra = "itexture1D"))]
551    ITexture1D,
552    /// `itexture2D` type specifier
553    #[lang_util(display(extra = "itexture2D"))]
554    ITexture2D,
555    /// `itexture3D` type specifier
556    #[lang_util(display(extra = "itexture3D"))]
557    ITexture3D,
558    /// `itextureCube` type specifier
559    #[lang_util(display(extra = "itextureCube"))]
560    ITextureCube,
561    /// `itexture2DRect` type specifier
562    #[lang_util(display(extra = "itexture2DRect"))]
563    ITexture2DRect,
564    /// `itexture1DArray` type specifier
565    #[lang_util(display(extra = "itexture1DArray"))]
566    ITexture1DArray,
567    /// `itexture2DArray` type specifier
568    #[lang_util(display(extra = "itexture2DArray"))]
569    ITexture2DArray,
570    /// `itextureBuffer` type specifier
571    #[lang_util(display(extra = "itextureBuffer"))]
572    ITextureBuffer,
573    /// `itexture2DMs` type specifier
574    #[lang_util(display(extra = "itexture2DMS"))]
575    ITexture2DMs,
576    /// `itexture2DMsArray` type specifier
577    #[lang_util(display(extra = "itexture2DMSArray"))]
578    ITexture2DMsArray,
579    /// `itextureCubeArray` type specifier
580    #[lang_util(display(extra = "itextureCubeArray"))]
581    ITextureCubeArray,
582    /// `sampler` type specifier
583    #[lang_util(display(extra = "sampler"))]
584    Sampler,
585    /// `samplerShadow` type specifier
586    #[lang_util(display(extra = "samplerShadow"))]
587    SamplerShadow,
588    /// `subpassInput` type specifier
589    #[lang_util(display(extra = "subpassInput"))]
590    SubpassInput,
591    /// `isubpassInput` type specifier
592    #[lang_util(display(extra = "isubpassInput"))]
593    ISubpassInput,
594    /// `usubpassInput` type specifier
595    #[lang_util(display(extra = "usubpassInput"))]
596    USubpassInput,
597    /// `subpassInputMs` type specifier
598    #[lang_util(display(extra = "subpassInputMS"))]
599    SubpassInputMs,
600    /// `isubpassInputMs` type specifier
601    #[lang_util(display(extra = "isubpassInputMS"))]
602    ISubpassInputMs,
603    /// `usubpassInputMs` type specifier
604    #[lang_util(display(extra = "usubpassInputMS"))]
605    USubpassInputMs,
606
607    // end GL_KHR_vulkan_glsl types
608    /// `struct` type specifier
609    #[lang_util(display(extra = "struct"))]
610    Struct(StructSpecifier),
611    /// Raw type name
612    TypeName(TypeName),
613}
614
615impl_node_content! {
616    /// Type alias for `Node<TypeSpecifierNonArrayData>`.
617    pub type TypeSpecifierNonArray = Node<TypeSpecifierNonArrayData>;
618}
619
620impl From<TypeName> for TypeSpecifierNonArrayData {
621    fn from(tn: TypeName) -> Self {
622        Self::TypeName(tn)
623    }
624}
625
626/// Type specifier.
627#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
628#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
629#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
630pub struct TypeSpecifierData {
631    /// Type name portion of the specifier
632    pub ty: TypeSpecifierNonArray,
633    /// Array part of the specifier
634    pub array_specifier: Option<ArraySpecifier>,
635}
636
637impl_node_content! {
638    /// Type alias for `Node<TypeSpecifierData>`.
639    pub type TypeSpecifier = Node<TypeSpecifierData>;
640}
641
642impl From<TypeSpecifierNonArray> for TypeSpecifierData {
643    fn from(ty: TypeSpecifierNonArray) -> Self {
644        Self {
645            ty,
646            array_specifier: None,
647        }
648    }
649}
650
651impl From<TypeSpecifierNonArrayData> for TypeSpecifierData {
652    fn from(ty: TypeSpecifierNonArrayData) -> Self {
653        Self {
654            ty: ty.into(),
655            array_specifier: None,
656        }
657    }
658}
659
660/// Struct specifier. Used to create new, user-defined types.
661#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
662#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
663#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
664pub struct StructSpecifierData {
665    /// Structure name
666    pub name: Option<TypeName>,
667    /// Field specifications
668    pub fields: Vec<StructFieldSpecifier>,
669}
670
671impl_node_content! {
672    /// Type alias for `Node<StructSpecifierData>`.
673    pub type StructSpecifier = Node<StructSpecifierData>;
674}
675
676/// Struct field specifier. Used to add fields to struct specifiers.
677#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
678#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
679#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
680pub struct StructFieldSpecifierData {
681    /// Type qualifiers for the field
682    pub qualifier: Option<TypeQualifier>,
683    /// Type of the field
684    pub ty: TypeSpecifier,
685    /// List of declared identifiers for this field
686    pub identifiers: Vec<ArrayedIdentifier>, // several identifiers of the same type
687}
688
689impl_node_content! {
690    /// Type alias for `Node<StructFieldSpecifierData>`.
691    pub type StructFieldSpecifier = Node<StructFieldSpecifierData>;
692}
693
694/// An identifier with an optional array specifier.
695#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
696#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
697#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
698pub struct ArrayedIdentifierData {
699    /// Raw identifier
700    pub ident: Identifier,
701    /// Attached array specification
702    pub array_spec: Option<ArraySpecifier>,
703}
704
705impl_node_content! {
706    /// Type alias for `Node<ArrayedIdentifierData>`.
707    pub type ArrayedIdentifier = Node<ArrayedIdentifierData>;
708}
709
710impl ArrayedIdentifierData {
711    /// Create a new [ArrayedIdentifier] from a raw identifier and a specification
712    pub fn new<I, AS>(ident: I, array_spec: AS) -> Self
713    where
714        I: Into<Identifier>,
715        AS: Into<Option<ArraySpecifier>>,
716    {
717        Self {
718            ident: ident.into(),
719            array_spec: array_spec.into(),
720        }
721    }
722}
723
724impl From<&str> for ArrayedIdentifierData {
725    fn from(ident: &str) -> Self {
726        Self {
727            ident: IdentifierData::from(ident).into(),
728            array_spec: None,
729        }
730    }
731}
732
733/// Type qualifier.
734#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
735#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
736#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
737pub struct TypeQualifierData {
738    /// List of type qualifiers
739    pub qualifiers: Vec<TypeQualifierSpec>,
740}
741
742impl_node_content! {
743    /// Type alias for `Node<TypeQualifierData>`.
744    pub type TypeQualifier = Node<TypeQualifierData>;
745}
746
747/// Type qualifier spec.
748#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
749#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
750#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
751pub enum TypeQualifierSpecData {
752    /// Storage qualifier
753    Storage(StorageQualifier),
754    /// Layout qualifier
755    Layout(LayoutQualifier),
756    /// Precision qualifier
757    Precision(PrecisionQualifier),
758    /// Interpolation qualifier
759    Interpolation(InterpolationQualifier),
760    /// `invariant` qualifier
761    Invariant,
762    /// `precise` qualifier
763    Precise,
764}
765
766impl_node_content! {
767    /// Type alias for `Node<TypeQualifierSpecData>`.
768    pub type TypeQualifierSpec = Node<TypeQualifierSpecData>;
769}
770
771/// Storage qualifier.
772#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
773#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
774#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
775pub enum StorageQualifierData {
776    /// `const` storage qualifier
777    #[lang_util(display(extra = "const"))]
778    Const,
779    /// `inout` storage qualifier
780    #[lang_util(display(extra = "inout"))]
781    InOut,
782    /// `in` storage qualifier
783    #[lang_util(display(extra = "in"))]
784    In,
785    /// `out` storage qualifier
786    #[lang_util(display(extra = "out"))]
787    Out,
788    /// `centroid` storage qualifier
789    #[lang_util(display(extra = "centroid"))]
790    Centroid,
791    /// `patch` storage qualifier
792    #[lang_util(display(extra = "patch"))]
793    Patch,
794    /// `sample` storage qualifier
795    #[lang_util(display(extra = "sample"))]
796    Sample,
797    /// `uniform` storage qualifier
798    #[lang_util(display(extra = "uniform"))]
799    Uniform,
800    /// `buffer` storage qualifier
801    #[lang_util(display(extra = "buffer"))]
802    Buffer,
803    /// `shared` storage qualifier
804    #[lang_util(display(extra = "shared"))]
805    Shared,
806    /// `coherent` storage qualifier
807    #[lang_util(display(extra = "coherent"))]
808    Coherent,
809    /// `volatile` storage qualifier
810    #[lang_util(display(extra = "volatile"))]
811    Volatile,
812    /// `restrict` storage qualifier
813    #[lang_util(display(extra = "restrict"))]
814    Restrict,
815    /// `readonly` storage qualifier
816    #[lang_util(display(extra = "readonly"))]
817    ReadOnly,
818    /// `writeonly` storage qualifier
819    #[lang_util(display(extra = "writeonly"))]
820    WriteOnly,
821    /// `attribute` storage qualifier
822    #[lang_util(display(extra = "attribute"))]
823    Attribute,
824    /// `varying` storage qualifier
825    #[lang_util(display(extra = "varying"))]
826    Varying,
827    // Note: the grammar says TYPE_NAME but type_specifier makes more sense given the definition of
828    // subroutine. The reference implementation is marked "to do".
829    /// `subroutine` storage qualifier
830    #[lang_util(display(extra = "subroutine"))]
831    Subroutine(Vec<TypeSpecifier>),
832}
833
834impl_node_content! {
835    /// Type alias for `Node<StorageQualifierData>`.
836    pub type StorageQualifier = Node<StorageQualifierData>;
837}
838
839/// Layout qualifier.
840#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
841#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
842#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
843pub struct LayoutQualifierData {
844    /// List of layout qualifiers
845    pub ids: Vec<LayoutQualifierSpec>,
846}
847
848impl_node_content! {
849    /// Type alias for `Node<LayoutQualifierData>`.
850    pub type LayoutQualifier = Node<LayoutQualifierData>;
851}
852
853/// Layout qualifier spec.
854#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
855#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
856#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
857pub enum LayoutQualifierSpecData {
858    /// An `ident = expr` layout qualifier
859    Identifier(Identifier, Option<Box<Expr>>),
860    /// `shared` layout qualifier
861    #[lang_util(display(extra = "shared"))]
862    Shared,
863}
864
865impl_node_content! {
866    /// Type alias for `Node<LayoutQualifierSpecData>`.
867    pub type LayoutQualifierSpec = Node<LayoutQualifierSpecData>;
868}
869
870/// Precision qualifier.
871#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
872#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
873#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
874pub enum PrecisionQualifierData {
875    /// `high` precision qualifier
876    #[lang_util(display(extra = "high"))]
877    High,
878    /// `medium` precision qualifier
879    #[lang_util(display(extra = "medium"))]
880    Medium,
881    /// `low` precision qualifier
882    #[lang_util(display(extra = "low"))]
883    Low,
884}
885
886impl_node_content! {
887    /// Type alias for `Node<PrecisionQualifierData>`.
888    pub type PrecisionQualifier = Node<PrecisionQualifierData>;
889}
890
891/// Interpolation qualifier.
892#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
893#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
894#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
895pub enum InterpolationQualifierData {
896    /// `smooth` interpolation qualifier
897    #[lang_util(display(extra = "smooth"))]
898    Smooth,
899    /// `flat` interpolation qualifier
900    #[lang_util(display(extra = "flat"))]
901    Flat,
902    /// `noperspective` interpolation qualifier
903    #[lang_util(display(extra = "noperspective"))]
904    NoPerspective,
905}
906
907impl_node_content! {
908    /// Type alias for `Node<InterpolationQualifierData>`.
909    pub type InterpolationQualifier = Node<InterpolationQualifierData>;
910}
911
912/// Fully specified type.
913#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
914#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
915#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
916pub struct FullySpecifiedTypeData {
917    /// Optional type qualifier
918    pub qualifier: Option<TypeQualifier>,
919    /// Type specifier
920    pub ty: TypeSpecifier,
921}
922
923impl_node_content! {
924    /// Type alias for `Node<FullySpecifiedTypeData>`.
925    pub type FullySpecifiedType = Node<FullySpecifiedTypeData>;
926}
927
928impl FullySpecifiedTypeData {
929    /// Create a new [FullySpecifiedType] from a [TypeSpecifierNonArray], with no qualifier and no
930    /// array specifier
931    pub fn new(ty: TypeSpecifierNonArray) -> Self {
932        Self {
933            qualifier: None,
934            ty: TypeSpecifierData {
935                ty,
936                array_specifier: None,
937            }
938            .into(),
939        }
940    }
941}
942
943impl From<TypeSpecifierNonArrayData> for FullySpecifiedTypeData {
944    fn from(ty: TypeSpecifierNonArrayData) -> Self {
945        Self::new(ty.into())
946    }
947}
948
949/// Dimensionality of an array.
950#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
951#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
952#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
953pub struct ArraySpecifierData {
954    /// List of all the dimensions – possibly unsized or explicitly-sized.
955    pub dimensions: Vec<ArraySpecifierDimension>,
956}
957
958impl_node_content! {
959    /// Type alias for `Node<ArraySpecifierData>`.
960    pub type ArraySpecifier = Node<ArraySpecifierData>;
961}
962
963/// One array specifier dimension.
964#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
965#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
966#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
967pub enum ArraySpecifierDimensionData {
968    /// `[]` dimension
969    Unsized,
970    /// `[expr]` dimension
971    ExplicitlySized(Box<Expr>),
972}
973
974impl_node_content! {
975    /// Type alias for `Node<ArraySpecifierDimensionData>`.
976    pub type ArraySpecifierDimension = Node<ArraySpecifierDimensionData>;
977}
978
979/// A declaration.
980#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
981#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
982#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
983pub enum DeclarationData {
984    /// Function prototype declaration
985    FunctionPrototype(FunctionPrototype),
986    /// List of declarators and initializers
987    InitDeclaratorList(InitDeclaratorList),
988    /// Precision declaration
989    Precision(PrecisionQualifier, TypeSpecifier),
990    /// Block declaration
991    Block(Block),
992    /// Invariant declaration
993    Invariant(Identifier),
994    /// Type-only declaration
995    TypeOnly(TypeQualifier),
996}
997
998impl_node_content! {
999    /// Type alias for `Node<DeclarationData>`.
1000    pub type Declaration = Node<DeclarationData>;
1001}
1002
1003/// A general purpose block, containing fields and possibly a list of declared identifiers. Semantic
1004/// is given with the storage qualifier.
1005#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1006#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1007#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1008pub struct BlockData {
1009    /// Block type qualifier
1010    pub qualifier: TypeQualifier,
1011    /// Block name
1012    pub name: Identifier,
1013    /// Declared fields
1014    pub fields: Vec<StructFieldSpecifier>,
1015    /// Associated identifiers
1016    pub identifier: Option<ArrayedIdentifier>,
1017}
1018
1019impl_node_content! {
1020    /// Type alias for `Node<BlockData>`.
1021    pub type Block = Node<BlockData>;
1022}
1023
1024/// Function identifier.
1025#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1026#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1027#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1028pub enum FunIdentifierData {
1029    /// Type name used for the function name (as a constructor)
1030    TypeSpecifier(Box<TypeSpecifier>),
1031    /// Expression used for the function name
1032    Expr(Box<Expr>),
1033}
1034
1035impl_node_content! {
1036    /// Type alias for `Node<FunIdentifierData>`.
1037    pub type FunIdentifier = Node<FunIdentifierData>;
1038}
1039
1040impl FunIdentifierData {
1041    /// Create a function identifier from an identifier
1042    pub fn ident(i: impl Into<IdentifierData>) -> Self {
1043        Self::Expr(Box::new(ExprData::Variable(i.into().into()).into()))
1044    }
1045
1046    /// Try to parse this function identifier as a raw identifier
1047    pub fn as_ident(&self) -> Option<&Identifier> {
1048        match self {
1049            Self::Expr(expr) => match &***expr {
1050                ExprData::Variable(ident) => Some(ident),
1051                _ => None,
1052            },
1053            _ => None,
1054        }
1055    }
1056
1057    /// Try to parse this function identifier as a mutable raw identifier
1058    pub fn as_ident_mut(&mut self) -> Option<&mut Identifier> {
1059        match self {
1060            Self::Expr(expr) => match &mut ***expr {
1061                ExprData::Variable(ident) => Some(ident),
1062                _ => None,
1063            },
1064            _ => None,
1065        }
1066    }
1067
1068    /// Try to parse this function identifier as a `glsl-lang-quote` Rust identifier
1069    pub fn as_rs_ident(&self) -> Option<&str> {
1070        if let Some(ident) = self.as_ident() {
1071            ident.as_rs_ident()
1072        } else {
1073            None
1074        }
1075    }
1076}
1077
1078/// Function prototype.
1079#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1080#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1081#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1082pub struct FunctionPrototypeData {
1083    /// Return type
1084    pub ty: FullySpecifiedType,
1085    /// Function name
1086    pub name: Identifier,
1087    /// Function parameters
1088    pub parameters: Vec<FunctionParameterDeclaration>,
1089}
1090
1091impl_node_content! {
1092    /// Type alias for `Node<FunctionPrototypeData>`.
1093    pub type FunctionPrototype = Node<FunctionPrototypeData>;
1094}
1095
1096/// Function parameter declaration.
1097#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1098#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1099#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1100pub enum FunctionParameterDeclarationData {
1101    /// Named parameter
1102    Named(Option<TypeQualifier>, FunctionParameterDeclarator),
1103    /// Unnamed parameter
1104    Unnamed(Option<TypeQualifier>, TypeSpecifier),
1105}
1106
1107impl_node_content! {
1108    /// Type alias for `Node<FunctionParameterDeclarationData>`.
1109    pub type FunctionParameterDeclaration = Node<FunctionParameterDeclarationData>;
1110}
1111
1112/// Function parameter declarator.
1113#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1114#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1115#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1116pub struct FunctionParameterDeclaratorData {
1117    /// Parameter type
1118    pub ty: TypeSpecifier,
1119    /// Parameter name
1120    pub ident: ArrayedIdentifier,
1121}
1122
1123impl_node_content! {
1124    /// Type alias for `Node<FunctionParameterDeclaratorData>`.
1125    pub type FunctionParameterDeclarator = Node<FunctionParameterDeclaratorData>;
1126}
1127
1128/// Init declarator list.
1129#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1130#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1131#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1132pub struct InitDeclaratorListData {
1133    /// First declaration
1134    pub head: SingleDeclaration,
1135    /// Following declarations
1136    pub tail: Vec<SingleDeclarationNoType>,
1137}
1138
1139impl_node_content! {
1140    /// Type alias for `Node<InitDeclaratorListData>`.
1141    pub type InitDeclaratorList = Node<InitDeclaratorListData>;
1142}
1143
1144/// Single declaration.
1145#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1146#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1147#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1148pub struct SingleDeclarationData {
1149    /// Declaration type
1150    pub ty: FullySpecifiedType,
1151    /// Declared identifier
1152    pub name: Option<Identifier>,
1153    /// Array specification
1154    pub array_specifier: Option<ArraySpecifier>,
1155    /// Initializer expression
1156    pub initializer: Option<Initializer>,
1157}
1158
1159impl_node_content! {
1160    /// Type alias for `Node<SingleDeclarationData>`.
1161    pub type SingleDeclaration = Node<SingleDeclarationData>;
1162}
1163
1164/// A single declaration with implicit, already-defined type.
1165#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1166#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1167#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1168pub struct SingleDeclarationNoTypeData {
1169    /// Declared identifier
1170    pub ident: ArrayedIdentifier,
1171    /// Initializer expression
1172    pub initializer: Option<Initializer>,
1173}
1174
1175impl_node_content! {
1176    /// Type alias for `Node<SingleDeclarationNoTypeData>`.
1177    pub type SingleDeclarationNoType = Node<SingleDeclarationNoTypeData>;
1178}
1179
1180/// Initializer.
1181#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1182#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1183#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1184pub enum InitializerData {
1185    /// Simple initializer
1186    Simple(Box<Expr>),
1187    /// Multiple initializer
1188    List(Vec<Initializer>),
1189}
1190
1191impl_node_content! {
1192    /// Type alias for `Node<InitializerData>`.
1193    pub type Initializer = Node<InitializerData>;
1194}
1195
1196impl From<ExprData> for InitializerData {
1197    fn from(e: ExprData) -> Self {
1198        Self::Simple(Box::new(e.into()))
1199    }
1200}
1201
1202impl From<Expr> for InitializerData {
1203    fn from(e: Expr) -> Self {
1204        Self::Simple(Box::new(e))
1205    }
1206}
1207
1208/// The most general form of an expression.
1209///
1210/// As you can see if you read the variant list, in GLSL, an assignment is an expression. This is a
1211/// bit silly but think of an assignment as a statement first then an expression which evaluates to
1212/// what the statement “returns”.
1213///
1214/// An expression is either an assignment or a list (comma) of assignments.
1215#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1216#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1217#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1218pub enum ExprData {
1219    /// A variable expression, using an identifier.
1220    Variable(Identifier),
1221    /// Integral constant expression.
1222    IntConst(i32),
1223    /// Unsigned integral constant expression.
1224    UIntConst(u32),
1225    /// Boolean constant expression.
1226    BoolConst(bool),
1227    /// Single precision floating expression.
1228    FloatConst(f32),
1229    /// Double precision floating expression.
1230    DoubleConst(f64),
1231    /// A unary expression, gathering a single expression and a unary operator.
1232    Unary(UnaryOp, Box<Expr>),
1233    /// A binary expression, gathering two expressions and a binary operator.
1234    Binary(BinaryOp, Box<Expr>, Box<Expr>),
1235    /// A ternary conditional expression, gathering three expressions.
1236    Ternary(Box<Expr>, Box<Expr>, Box<Expr>),
1237    /// An assignment is also an expression. Gathers an expression that defines what to assign to, an
1238    /// assignment operator and the value to associate with.
1239    Assignment(Box<Expr>, AssignmentOp, Box<Expr>),
1240    /// Add an array specifier to an expression.
1241    Bracket(Box<Expr>, Box<Expr>),
1242    /// A functional call. It has a function identifier and a list of expressions (arguments).
1243    FunCall(FunIdentifier, Vec<Expr>),
1244    /// An expression associated with a field selection (struct).
1245    Dot(Box<Expr>, Identifier),
1246    /// Post-incrementation of an expression.
1247    PostInc(Box<Expr>),
1248    /// Post-decrementation of an expression.
1249    PostDec(Box<Expr>),
1250    /// An expression that contains several, separated with comma.
1251    Comma(Box<Expr>, Box<Expr>),
1252}
1253
1254impl_node_content! {
1255    /// Type alias for `Node<ExprData>`.
1256    pub type Expr = Node<ExprData>;
1257}
1258
1259impl ExprData {
1260    /// Construct an `Expr::Variable(name)` from an identifier `name`
1261    pub fn variable(name: impl Into<IdentifierData>) -> Self {
1262        Self::Variable(name.into().into())
1263    }
1264
1265    /// Try to parse this function identifier as a `glsl-lang-quote` Rust identifier
1266    pub fn as_rs_ident(&self) -> Option<&str> {
1267        match self {
1268            Self::Variable(ident) => ident.as_rs_ident(),
1269            _ => None,
1270        }
1271    }
1272}
1273
1274impl From<i32> for ExprData {
1275    fn from(x: i32) -> ExprData {
1276        Self::IntConst(x)
1277    }
1278}
1279
1280impl From<u32> for ExprData {
1281    fn from(x: u32) -> ExprData {
1282        Self::UIntConst(x)
1283    }
1284}
1285
1286impl From<bool> for ExprData {
1287    fn from(x: bool) -> ExprData {
1288        Self::BoolConst(x)
1289    }
1290}
1291
1292impl From<f32> for ExprData {
1293    fn from(x: f32) -> ExprData {
1294        Self::FloatConst(x)
1295    }
1296}
1297
1298impl From<f64> for ExprData {
1299    fn from(x: f64) -> ExprData {
1300        Self::DoubleConst(x)
1301    }
1302}
1303
1304/// All unary operators that exist in GLSL.
1305#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1306#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1307#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1308pub enum UnaryOpData {
1309    /// `++` unary operator
1310    #[lang_util(display(extra = "++"))]
1311    Inc,
1312    /// `--` unary operator
1313    #[lang_util(display(extra = "--"))]
1314    Dec,
1315    /// `+` unary operator
1316    #[lang_util(display(extra = "+"))]
1317    Add,
1318    /// `-` unary operator
1319    #[lang_util(display(extra = "-"))]
1320    Minus,
1321    /// `!` unary operator
1322    #[lang_util(display(extra = "!"))]
1323    Not,
1324    /// `~` unary operator
1325    #[lang_util(display(extra = "~"))]
1326    Complement,
1327}
1328
1329impl_node_content! {
1330    /// Type alias for `Node<UnaryOpData>`.
1331    pub type UnaryOp = Node<UnaryOpData>;
1332}
1333
1334/// All binary operators that exist in GLSL.
1335#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1337#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1338pub enum BinaryOpData {
1339    /// `||` binary operator
1340    #[lang_util(display(extra = "||"))]
1341    Or,
1342    /// `^^` binary operator
1343    #[lang_util(display(extra = "^^"))]
1344    Xor,
1345    /// `&&` binary operator
1346    #[lang_util(display(extra = "&&"))]
1347    And,
1348    /// `|` binary operator
1349    #[lang_util(display(extra = "|"))]
1350    BitOr,
1351    /// `^` binary operator
1352    #[lang_util(display(extra = "^"))]
1353    BitXor,
1354    /// `&` binary operator
1355    #[lang_util(display(extra = "&"))]
1356    BitAnd,
1357    /// `==` binary operator
1358    #[lang_util(display(extra = "=="))]
1359    Equal,
1360    /// `!=` binary operator
1361    #[lang_util(display(extra = "!="))]
1362    NonEqual,
1363    /// `<` binary operator
1364    #[lang_util(display(extra = "<"))]
1365    Lt,
1366    /// `>` binary operator
1367    #[lang_util(display(extra = ">"))]
1368    Gt,
1369    /// `<=` binary operator
1370    #[lang_util(display(extra = "<="))]
1371    Lte,
1372    /// `>=` binary operator
1373    #[lang_util(display(extra = ">="))]
1374    Gte,
1375    /// `<<` binary operator
1376    #[lang_util(display(extra = "<<"))]
1377    LShift,
1378    /// `>>` binary operator
1379    #[lang_util(display(extra = ">>"))]
1380    RShift,
1381    /// `+` binary operator
1382    #[lang_util(display(extra = "+"))]
1383    Add,
1384    /// `-` binary operator
1385    #[lang_util(display(extra = "-"))]
1386    Sub,
1387    /// `*` binary operator
1388    #[lang_util(display(extra = "*"))]
1389    Mult,
1390    /// `/` binary operator
1391    #[lang_util(display(extra = "/"))]
1392    Div,
1393    /// `%` binary operator
1394    #[lang_util(display(extra = "%"))]
1395    Mod,
1396}
1397
1398impl_node_content! {
1399    /// Type alias for `Node<BinaryOpData>`.
1400    pub type BinaryOp = Node<BinaryOpData>;
1401}
1402
1403/// All possible operators for assigning expressions.
1404#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1405#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1406#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1407pub enum AssignmentOpData {
1408    /// `=` assignment operator
1409    #[lang_util(display(extra = "="))]
1410    Equal,
1411    /// `*` assignment operator
1412    #[lang_util(display(extra = "*"))]
1413    Mult,
1414    /// `/=` assignment operator
1415    #[lang_util(display(extra = "/="))]
1416    Div,
1417    /// `%=` assignment operator
1418    #[lang_util(display(extra = "%="))]
1419    Mod,
1420    /// `+=` assignment operator
1421    #[lang_util(display(extra = "+="))]
1422    Add,
1423    /// `-=` assignment operator
1424    #[lang_util(display(extra = "-="))]
1425    Sub,
1426    /// `<<=` assignment operator
1427    #[lang_util(display(extra = "<<="))]
1428    LShift,
1429    /// `>>=` assignment operator
1430    #[lang_util(display(extra = ">>="))]
1431    RShift,
1432    /// `&=` assignment operator
1433    #[lang_util(display(extra = "&="))]
1434    And,
1435    /// `^=` assignment operator
1436    #[lang_util(display(extra = "^="))]
1437    Xor,
1438    /// `|=` assignment operator
1439    #[lang_util(display(extra = "|="))]
1440    Or,
1441}
1442
1443impl_node_content! {
1444    /// Type alias for `Node<AssignmentOpData>`.
1445    pub type AssignmentOp = Node<AssignmentOpData>;
1446}
1447
1448/// Starting rule.
1449#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1450#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1451#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1452pub struct TranslationUnit(pub Vec<ExternalDeclaration>);
1453
1454impl NodeContent for TranslationUnit {}
1455
1456/// External declaration.
1457#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1458#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1459#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1460pub enum ExternalDeclarationData {
1461    /// Preprocessor directive
1462    Preprocessor(Preprocessor),
1463    /// Function definition
1464    FunctionDefinition(FunctionDefinition),
1465    /// Declaration
1466    Declaration(Declaration),
1467}
1468
1469impl_node_content! {
1470    /// Type alias for `Node<ExternalDeclarationData>`.
1471    pub type ExternalDeclaration = Node<ExternalDeclarationData>;
1472}
1473
1474/// Function definition.
1475#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1476#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1477#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1478pub struct FunctionDefinitionData {
1479    /// Function prototype
1480    pub prototype: FunctionPrototype,
1481    /// Function body
1482    pub statement: CompoundStatement,
1483}
1484
1485impl_node_content! {
1486    /// Type alias for `Node<FunctionDefinitionData>`.
1487    pub type FunctionDefinition = Node<FunctionDefinitionData>;
1488}
1489
1490/// Compound statement (with no new scope).
1491#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1492#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1493#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1494pub struct CompoundStatementData {
1495    /// List of statements
1496    pub statement_list: Vec<Statement>,
1497}
1498
1499impl_node_content! {
1500    /// Type alias for `Node<CompoundStatementData>`.
1501    pub type CompoundStatement = Node<CompoundStatementData>;
1502}
1503
1504impl FromIterator<Statement> for CompoundStatementData {
1505    fn from_iter<T>(iter: T) -> Self
1506    where
1507        T: IntoIterator<Item = Statement>,
1508    {
1509        Self {
1510            statement_list: iter.into_iter().collect(),
1511        }
1512    }
1513}
1514
1515/// Statement.
1516#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1517#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1518#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1519pub enum StatementData {
1520    /// Declaration
1521    Declaration(Declaration),
1522    /// Expression statement
1523    Expression(ExprStatement),
1524    /// `if/...` statement
1525    Selection(SelectionStatement),
1526    /// `switch` statement
1527    Switch(SwitchStatement),
1528    /// Switch statement case label
1529    CaseLabel(CaseLabel),
1530    /// Iteration statement
1531    Iteration(IterationStatement),
1532    /// Jump statement
1533    Jump(JumpStatement),
1534    /// Statement block
1535    Compound(CompoundStatement),
1536}
1537
1538impl_node_content! {
1539    /// Type alias for `Node<StatementData>`.
1540    pub type Statement = Node<StatementData>;
1541}
1542
1543impl StatementData {
1544    /// Declare a new variable.
1545    ///
1546    /// `ty` is the type of the variable, `name` the name of the binding to create,
1547    /// `array_specifier` an optional argument to make your binding an array and
1548    /// `initializer`
1549    pub fn declare_var<T, N, A, I>(ty: T, name: N, array_specifier: A, initializer: I) -> Self
1550    where
1551        T: Into<FullySpecifiedTypeData>,
1552        N: Into<IdentifierData>,
1553        A: Into<Option<ArraySpecifier>>,
1554        I: Into<Option<Initializer>>,
1555    {
1556        Self::Declaration(
1557            DeclarationData::InitDeclaratorList(
1558                InitDeclaratorListData {
1559                    head: SingleDeclarationData {
1560                        ty: ty.into().into(),
1561                        name: Some(name.into().into()),
1562                        array_specifier: array_specifier.into(),
1563                        initializer: initializer.into(),
1564                    }
1565                    .into(),
1566                    tail: Vec::new(),
1567                }
1568                .into(),
1569            )
1570            .into(),
1571        )
1572    }
1573}
1574
1575/// Expression statement.
1576#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1577#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1578#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1579pub struct ExprStatementData(pub Option<Expr>);
1580
1581impl_node_content! {
1582    /// Type alias for `Node<ExprStatementData>`.
1583    pub type ExprStatement = Node<ExprStatementData>;
1584}
1585
1586/// Selection statement.
1587#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1588#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1589#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1590pub struct SelectionStatementData {
1591    /// Condition to evaluate
1592    pub cond: Box<Expr>,
1593    /// Rest of the selection statement
1594    pub rest: SelectionRestStatement,
1595}
1596
1597impl_node_content! {
1598    /// Type alias for `Node<SelectionStatementData>`.
1599    pub type SelectionStatement = Node<SelectionStatementData>;
1600}
1601
1602/// Condition.
1603#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1604#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1605#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1606pub enum ConditionData {
1607    /// An expression
1608    Expr(Expr),
1609    /// A variable declaration used as a condition
1610    Assignment(Box<FullySpecifiedType>, Identifier, Initializer),
1611}
1612
1613impl_node_content! {
1614    /// Type alias for `Node<ConditionData>`.
1615    pub type Condition = Node<ConditionData>;
1616}
1617
1618/// Selection rest statement.
1619#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1621#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1622pub enum SelectionRestStatementData {
1623    /// Body of the if.
1624    Statement(Box<Statement>),
1625    /// The first argument is the body of the if, the rest is the next statement.
1626    Else(Box<Statement>, Box<Statement>),
1627}
1628
1629impl_node_content! {
1630    /// Type alias for `Node<SelectionRestStatementData>`.
1631    pub type SelectionRestStatement = Node<SelectionRestStatementData>;
1632}
1633
1634/// Switch statement.
1635#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1636#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1637#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1638pub struct SwitchStatementData {
1639    /// Expression to evaluate and switch on
1640    pub head: Box<Expr>,
1641    /// Body of the switch statement
1642    pub body: Vec<Statement>,
1643}
1644
1645impl_node_content! {
1646    /// Type alias for `Node<SwitchStatementData>`.
1647    pub type SwitchStatement = Node<SwitchStatementData>;
1648}
1649
1650/// Case label statement.
1651#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1652#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1653#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1654pub enum CaseLabelData {
1655    /// `case:` case label
1656    Case(Box<Expr>),
1657    /// `default:` case label
1658    Def,
1659}
1660
1661impl_node_content! {
1662    /// Type alias for `Node<CaseLabelData>`.
1663    pub type CaseLabel = Node<CaseLabelData>;
1664}
1665
1666/// Iteration statement.
1667#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1668#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1669#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1670pub enum IterationStatementData {
1671    /// `while` iteration statement
1672    #[lang_util(display(extra = "while"))]
1673    While(Condition, Box<Statement>),
1674    /// `do` iteration statement
1675    #[lang_util(display(extra = "do"))]
1676    DoWhile(Box<Statement>, Box<Expr>),
1677    /// `for` iteration statement
1678    #[lang_util(display(extra = "for"))]
1679    For(ForInitStatement, ForRestStatement, Box<Statement>),
1680}
1681
1682impl_node_content! {
1683    /// Type alias for `Node<IterationStatementData>`.
1684    pub type IterationStatement = Node<IterationStatementData>;
1685}
1686
1687/// For init statement.
1688#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1689#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1690#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1691pub enum ForInitStatementData {
1692    /// Expression
1693    Expression(Option<Expr>),
1694    /// Variable declaration
1695    Declaration(Box<Declaration>),
1696}
1697
1698impl_node_content! {
1699    /// Type alias for `Node<ForInitStatementData>`.
1700    pub type ForInitStatement = Node<ForInitStatementData>;
1701}
1702
1703/// For init statement.
1704#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1705#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1706#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1707pub struct ForRestStatementData {
1708    /// Loop condition
1709    pub condition: Option<Condition>,
1710    /// Loop increment operation
1711    pub post_expr: Option<Box<Expr>>,
1712}
1713
1714impl_node_content! {
1715    /// Type alias for `Node<ForRestStatementData>`.
1716    pub type ForRestStatement = Node<ForRestStatementData>;
1717}
1718
1719/// Jump statement.
1720#[derive(Clone, Debug, PartialEq, NodeContentDisplay)]
1721#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1722#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1723pub enum JumpStatementData {
1724    /// `continue` jump statement
1725    #[lang_util(display(extra = "continue"))]
1726    Continue,
1727    /// `break` jump statement
1728    #[lang_util(display(extra = "break"))]
1729    Break,
1730    /// `return` jump statement
1731    #[lang_util(display(extra = "return"))]
1732    Return(Option<Box<Expr>>),
1733    /// `discard` jump statement
1734    #[lang_util(display(extra = "discard"))]
1735    Discard,
1736}
1737
1738impl_node_content! {
1739    /// Type alias for `Node<JumpStatementData>`.
1740    pub type JumpStatement = Node<JumpStatementData>;
1741}
1742
1743/// Some basic preprocessor directives.
1744///
1745/// As it’s important to carry them around the AST because they cannot be substituted in a normal
1746/// preprocessor (they’re used by GPU’s compilers), those preprocessor directives are available for
1747/// inspection.
1748#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1749#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1750#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1751pub enum PreprocessorData {
1752    /// `#define` preprocessor directive
1753    #[lang_util(display(extra = "#define"))]
1754    Define(PreprocessorDefine),
1755    /// `#else` preprocessor directive
1756    #[lang_util(display(extra = "#else"))]
1757    Else,
1758    /// `#elseif` preprocessor directive
1759    #[lang_util(display(extra = "#elseif"))]
1760    ElseIf(PreprocessorElseIf),
1761    /// `#endif` preprocessor directive
1762    #[lang_util(display(extra = "#endif"))]
1763    EndIf,
1764    /// `#error` preprocessor directive
1765    #[lang_util(display(extra = "#error"))]
1766    Error(PreprocessorError),
1767    /// `#if` preprocessor directive
1768    #[lang_util(display(extra = "#if"))]
1769    If(PreprocessorIf),
1770    /// `#ifdef` preprocessor directive
1771    #[lang_util(display(extra = "#ifdef"))]
1772    IfDef(PreprocessorIfDef),
1773    /// `#ifndef` preprocessor directive
1774    #[lang_util(display(extra = "#ifndef"))]
1775    IfNDef(PreprocessorIfNDef),
1776    /// `#include` preprocessor directive
1777    #[lang_util(display(extra = "#include"))]
1778    Include(PreprocessorInclude),
1779    /// `#line` preprocessor directive
1780    #[lang_util(display(extra = "#line"))]
1781    Line(PreprocessorLine),
1782    /// `#pragma` preprocessor directive
1783    #[lang_util(display(extra = "#pragma"))]
1784    Pragma(PreprocessorPragma),
1785    /// `#undef` preprocessor directive
1786    #[lang_util(display(extra = "#undef"))]
1787    Undef(PreprocessorUndef),
1788    /// `#version` preprocessor directive
1789    #[lang_util(display(extra = "#version"))]
1790    Version(PreprocessorVersion),
1791    /// `#extension` preprocessor directive
1792    #[lang_util(display(extra = "#extension"))]
1793    Extension(PreprocessorExtension),
1794}
1795
1796impl_node_content! {
1797    /// Type alias for `Node<PreprocessorData>`.
1798    pub type Preprocessor = Node<PreprocessorData>;
1799}
1800
1801/// A #define preprocessor directive.
1802///
1803/// Allows any expression but only Integer and Float literals make sense
1804#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1805#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1806#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1807pub enum PreprocessorDefineData {
1808    /// A preprocessor definition
1809    ObjectLike {
1810        /// Identifier for the definition
1811        ident: Identifier,
1812        /// Associated value
1813        value: String,
1814    },
1815
1816    /// A preprocessor function definition
1817    FunctionLike {
1818        /// Identifier for the definition
1819        ident: Identifier,
1820        /// List of arguments for the function
1821        args: Vec<Identifier>,
1822        /// Associated value
1823        value: String,
1824    },
1825}
1826
1827impl_node_content! {
1828    /// Type alias for `Node<PreprocessorDefineData>`.
1829    pub type PreprocessorDefine = Node<PreprocessorDefineData>;
1830}
1831
1832/// An #else preprocessor directive.
1833#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1834#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1835#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1836pub struct PreprocessorElseIfData {
1837    /// Condition expression
1838    #[lang_util(display(extra))]
1839    pub condition: String,
1840}
1841
1842impl_node_content! {
1843    /// Type alias for `Node<PreprocessorElseIfData>`.
1844    pub type PreprocessorElseIf = Node<PreprocessorElseIfData>;
1845}
1846
1847/// An #error preprocessor directive.
1848#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1849#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1850#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1851pub struct PreprocessorErrorData {
1852    /// Error message
1853    #[lang_util(display(extra))]
1854    pub message: String,
1855}
1856
1857impl_node_content! {
1858    /// Type alias for `Node<PreprocessorErrorData>`.
1859    pub type PreprocessorError = Node<PreprocessorErrorData>;
1860}
1861
1862/// An #if preprocessor directive.
1863#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1864#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1865#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1866pub struct PreprocessorIfData {
1867    /// Condition expression
1868    #[lang_util(display(extra))]
1869    pub condition: String,
1870}
1871
1872impl_node_content! {
1873    /// Type alias for `Node<PreprocessorIfData>`.
1874    pub type PreprocessorIf = Node<PreprocessorIfData>;
1875}
1876
1877/// An #ifdef preprocessor directive.
1878#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1879#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1880#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1881pub struct PreprocessorIfDefData {
1882    /// Identifier to test
1883    #[lang_util(display(extra))]
1884    pub ident: Identifier,
1885}
1886
1887impl_node_content! {
1888    /// Type alias for `Node<PreprocessorIfDefData>`.
1889    pub type PreprocessorIfDef = Node<PreprocessorIfDefData>;
1890}
1891
1892/// A #ifndef preprocessor directive.
1893#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1894#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1895#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1896pub struct PreprocessorIfNDefData {
1897    /// Identifier to test
1898    #[lang_util(display(extra))]
1899    pub ident: Identifier,
1900}
1901
1902impl_node_content! {
1903    /// Type alias for `Node<PreprocessorIfNDefData>`.
1904    pub type PreprocessorIfNDef = Node<PreprocessorIfNDefData>;
1905}
1906
1907/// An #include name annotation.
1908#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1909#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1910#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1911pub struct PreprocessorIncludeData {
1912    /// Include path
1913    pub path: Path,
1914}
1915
1916impl_node_content! {
1917    /// Type alias for `Node<PreprocessorIncludeData>`.
1918    pub type PreprocessorInclude = Node<PreprocessorIncludeData>;
1919}
1920
1921/// A #line preprocessor directive.
1922#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1923#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1924#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1925pub struct PreprocessorLineData {
1926    /// Line index
1927    #[lang_util(display(extra))]
1928    pub line: u32,
1929    /// Source index
1930    pub source_string_number: Option<u32>,
1931}
1932
1933impl_node_content! {
1934    /// Type alias for `Node<PreprocessorLineData>`.
1935    pub type PreprocessorLine = Node<PreprocessorLineData>;
1936}
1937
1938/// A #pragma preprocessor directive.
1939/// Holds compiler-specific command.
1940#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1941#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1942#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1943pub struct PreprocessorPragmaData {
1944    /// Raw pragma text
1945    #[lang_util(display(extra))]
1946    pub command: String,
1947}
1948
1949impl_node_content! {
1950    /// Type alias for `Node<PreprocessorPragmaData>`.
1951    pub type PreprocessorPragma = Node<PreprocessorPragmaData>;
1952}
1953
1954/// A #undef preprocessor directive.
1955#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1956#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1957#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1958pub struct PreprocessorUndefData {
1959    /// Identifier to undefine
1960    #[lang_util(display(extra))]
1961    pub name: Identifier,
1962}
1963
1964impl_node_content! {
1965    /// Type alias for `Node<PreprocessorUndefData>`.
1966    pub type PreprocessorUndef = Node<PreprocessorUndefData>;
1967}
1968
1969/// A #version preprocessor directive.
1970#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1971#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1972#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1973pub struct PreprocessorVersionData {
1974    /// Version number
1975    #[lang_util(display(extra))]
1976    pub version: u16,
1977    /// Version profile
1978    pub profile: Option<PreprocessorVersionProfile>,
1979}
1980
1981impl_node_content! {
1982    /// Type alias for `Node<PreprocessorVersionData>`.
1983    pub type PreprocessorVersion = Node<PreprocessorVersionData>;
1984}
1985
1986/// A #version profile annotation.
1987#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
1988#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1989#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
1990pub enum PreprocessorVersionProfileData {
1991    /// `core` version profile
1992    #[lang_util(display(extra = "core"))]
1993    Core,
1994    /// `compatibility` version profile
1995    #[lang_util(display(extra = "compatibility"))]
1996    Compatibility,
1997    /// `es` version profile
1998    #[lang_util(display(extra = "es"))]
1999    Es,
2000}
2001
2002impl_node_content! {
2003    /// Type alias for `Node<PreprocessorVersionProfileData>`.
2004    pub type PreprocessorVersionProfile = Node<PreprocessorVersionProfileData>;
2005}
2006
2007/// An #extension preprocessor directive.
2008#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
2009#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2010#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
2011pub struct PreprocessorExtensionData {
2012    /// Name of the target extension
2013    pub name: PreprocessorExtensionName,
2014    /// Behavior for the extension
2015    pub behavior: Option<PreprocessorExtensionBehavior>,
2016}
2017
2018impl_node_content! {
2019    /// Type alias for `Node<PreprocessorExtensionData>`.
2020    pub type PreprocessorExtension = Node<PreprocessorExtensionData>;
2021}
2022
2023/// An #extension name annotation.
2024#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
2025#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2026#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
2027pub enum PreprocessorExtensionNameData {
2028    /// All extensions you could ever imagine in your whole lifetime (how crazy is that!).
2029    #[lang_util(display(extra = "all"))]
2030    All,
2031    /// A specific extension.
2032    Specific(SmolStr),
2033}
2034
2035impl_node_content! {
2036    /// Type alias for `Node<PreprocessorExtensionNameData>`.
2037    pub type PreprocessorExtensionName = Node<PreprocessorExtensionNameData>;
2038}
2039
2040/// An #extension behavior annotation.
2041#[derive(Clone, Debug, PartialEq, Eq, NodeContentDisplay)]
2042#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2043#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
2044pub enum PreprocessorExtensionBehaviorData {
2045    /// `require` preprocessor extension behavior
2046    #[lang_util(display(extra = "require"))]
2047    Require,
2048    /// `enable` preprocessor extension behavior
2049    #[lang_util(display(extra = "enable"))]
2050    Enable,
2051    /// `warn` preprocessor extension behavior
2052    #[lang_util(display(extra = "warn"))]
2053    Warn,
2054    /// `disable` preprocessor extension behavior
2055    #[lang_util(display(extra = "disable"))]
2056    Disable,
2057}
2058
2059impl_node_content! {
2060    /// Type alias for `Node<PreprocessorExtensionBehaviorData>`.
2061    pub type PreprocessorExtensionBehavior = Node<PreprocessorExtensionBehaviorData>;
2062}
2063
2064/// A comment
2065#[derive(Debug, Clone, PartialEq, Eq, NodeContentDisplay)]
2066#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2067#[cfg_attr(feature = "serde", serde(crate = "rserde"))]
2068pub enum CommentData {
2069    /// Single-line comment
2070    Single(String),
2071    /// Multi-line comment
2072    Multi(String),
2073}
2074
2075impl_node_content! {
2076    /// Type alias for `Node<CommentData>`.
2077    pub type Comment = Node<CommentData>;
2078}
2079
2080impl CommentData {
2081    /// Get the comment's text, regardless of its type
2082    pub fn text(&self) -> &str {
2083        match self {
2084            Self::Single(s) => s,
2085            Self::Multi(s) => s,
2086        }
2087    }
2088
2089    /// true if this comment is a single-line comment
2090    pub fn is_single(&self) -> bool {
2091        matches!(self, Self::Multi(_))
2092    }
2093
2094    /// true if this comment is a multi-line comment
2095    pub fn is_multi(&self) -> bool {
2096        matches!(self, Self::Multi(_))
2097    }
2098}