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