Skip to main content

wgsl_types/
display.rs

1use std::fmt::Display;
2
3use itertools::Itertools;
4
5use crate::{
6    CallSignature,
7    inst::{
8        ArrayInstance, AtomicInstance, Instance, LiteralInstance, MatInstance, MemView,
9        PtrInstance, RefInstance, StructInstance, VecInstance,
10    },
11    syntax::Enumerant,
12    tplt::TpltParam,
13    ty::{SamplerType, TextureType, Ty, Type},
14};
15
16impl Display for TpltParam {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        match self {
19            TpltParam::Type(ty) => write!(f, "{ty}"),
20            TpltParam::Instance(inst) => write!(f, "{inst}"),
21            TpltParam::Enumerant(name) => write!(f, "{name}"),
22        }
23    }
24}
25
26impl Display for CallSignature {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        let name = &self.name;
29        let tplt = self.tplt.as_ref().map(|tplt| tplt.iter().format(", "));
30        let args = self.args.iter().format(", ");
31
32        if let Some(tplt) = tplt {
33            write!(f, "{name}<{tplt}>({args})")
34        } else {
35            write!(f, "{name}({args})")
36        }
37    }
38}
39
40impl Display for Instance {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        match self {
43            Instance::Literal(inst) => write!(f, "{inst}"),
44            Instance::Struct(inst) => write!(f, "{inst}"),
45            Instance::Array(inst) => write!(f, "{inst}"),
46            Instance::Vec(inst) => write!(f, "{inst}"),
47            Instance::Mat(inst) => write!(f, "{inst}"),
48            Instance::Ptr(inst) => write!(f, "{inst}"),
49            Instance::Ref(inst) => write!(f, "{inst}"),
50            Instance::Atomic(inst) => write!(f, "{inst}"),
51            Instance::Opaque(ty) => write!(f, "__opaque<{ty}>"),
52        }
53    }
54}
55
56impl Display for LiteralInstance {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        match self {
59            LiteralInstance::Bool(lit) => write!(f, "{lit}"),
60            LiteralInstance::AbstractInt(lit) => write!(f, "{lit}"),
61            LiteralInstance::AbstractFloat(lit) => write!(f, "{lit:?}"), // using the Debug formatter to print the trailing .0 in floats representing integers. because format!("{}", 3.0f32) == "3"
62            LiteralInstance::I32(lit) => write!(f, "{lit}i"),
63            LiteralInstance::U32(lit) => write!(f, "{lit}u"),
64            LiteralInstance::F32(lit) => write!(f, "{lit}f"),
65            LiteralInstance::F16(lit) => write!(f, "{lit}h"),
66            #[cfg(feature = "naga-ext")]
67            LiteralInstance::I64(lit) => write!(f, "{lit}li"),
68            #[cfg(feature = "naga-ext")]
69            LiteralInstance::U64(lit) => write!(f, "{lit}lu"),
70            #[cfg(feature = "naga-ext")]
71            LiteralInstance::F64(lit) => write!(f, "{lit}lf"),
72        }
73    }
74}
75
76impl Display for StructInstance {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        let name = &self.ty.name;
79        let comps = self
80            .members
81            .iter()
82            .map(|inst| format!("{inst}"))
83            .format(", ");
84        write!(f, "{name}({comps})")
85    }
86}
87
88impl Display for ArrayInstance {
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        let comps = self.iter().format(", ");
91        write!(f, "array({comps})")
92    }
93}
94
95impl Display for VecInstance {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        let n = self.n();
98        let comps = self.iter().format(", ");
99        write!(f, "vec{n}({comps})")
100    }
101}
102
103impl Display for MatInstance {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        let c = self.c();
106        let r = self.r();
107        let comps = (0..c).map(|i| self.col(i).unwrap()).format(", ");
108        write!(f, "mat{c}x{r}({comps})")
109    }
110}
111
112impl Display for Enumerant {
113    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114        match self {
115            Enumerant::AccessMode(access_mode) => write!(f, "{access_mode}"),
116            Enumerant::AddressSpace(address_space) => write!(f, "{address_space}"),
117            Enumerant::TexelFormat(texel_format) => write!(f, "{texel_format}"),
118            #[cfg(feature = "naga-ext")]
119            Enumerant::AccelerationStructureTag(tag) => write!(f, "{tag}"),
120        }
121    }
122}
123
124impl Display for PtrInstance {
125    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126        let space = &self.ptr.space;
127        let ty = &self.ptr.ty;
128        let access = &self.ptr.access;
129        let val = self.ptr.read().expect("invalid reference");
130        write!(f, "ptr<{space}, {ty}, {access}>({val})")
131    }
132}
133
134impl Display for RefInstance {
135    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136        let space = &self.space;
137        let ty = &self.ty;
138        let access = &self.access;
139        let val = self.read().expect("invalid reference");
140        write!(f, "ref<{space}, {ty}, {access}>({val})")
141    }
142}
143
144impl Display for MemView {
145    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146        fn fmt_view(f: &mut std::fmt::Formatter<'_>, view: &MemView) -> std::fmt::Result {
147            match view {
148                MemView::Whole => Ok(()),
149                MemView::Member(m, v) => {
150                    write!(f, ":{m}")?;
151                    fmt_view(f, v)
152                }
153                MemView::Index(i, v) => {
154                    write!(f, ":{i}")?;
155                    fmt_view(f, v)
156                }
157            }
158        }
159
160        fmt_view(f, self)
161    }
162}
163
164impl Display for AtomicInstance {
165    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166        let ty = &self.inner_ty();
167        let val = self.inner();
168        write!(f, "atomic<{ty}>({val})")
169    }
170}
171
172impl Display for Type {
173    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174        match self {
175            Type::Bool => write!(f, "bool"),
176            Type::AbstractInt => write!(f, "AbstractInt"),
177            Type::AbstractFloat => write!(f, "AbstractFloat"),
178            Type::I32 => write!(f, "i32"),
179            Type::U32 => write!(f, "u32"),
180            Type::F32 => write!(f, "f32"),
181            Type::F16 => write!(f, "f16"),
182            Type::Struct(s) => write!(f, "{}", s.name),
183            Type::Array(ty, Some(n)) => write!(f, "array<{ty}, {n}>"),
184            Type::Array(ty, None) => write!(f, "array<{ty}>"),
185            Type::Vec(n, ty) => write!(f, "vec{n}<{ty}>"),
186            Type::Mat(m, n, ty) => write!(f, "mat{m}x{n}<{ty}>"),
187            Type::Atomic(ty) => write!(f, "atomic<{ty}>"),
188            Type::Ptr(a_s, ty, a_m) => write!(f, "ptr<{a_s}, {ty}, {a_m}>"),
189            Type::Ref(a_s, ty, a_m) => write!(f, "ref<{a_s}, {ty}, {a_m}>"),
190            Type::Texture(texture_type) => texture_type.fmt(f),
191            Type::Sampler(sampler_type) => sampler_type.fmt(f),
192            Type::Unknown => write!(f, "unknown"),
193            #[cfg(feature = "naga-ext")]
194            Type::I64 => write!(f, "i64"),
195            #[cfg(feature = "naga-ext")]
196            Type::U64 => write!(f, "u64"),
197            #[cfg(feature = "naga-ext")]
198            Type::F64 => write!(f, "f64"),
199            #[cfg(feature = "naga-ext")]
200            Type::BindingArray(ty, Some(n)) => write!(f, "binding_array<{ty}, {n}>"),
201            #[cfg(feature = "naga-ext")]
202            Type::BindingArray(ty, None) => write!(f, "binding_array<{ty}>"),
203            #[cfg(feature = "naga-ext")]
204            Type::RayQuery(None) => write!(f, "ray_query"),
205            #[cfg(feature = "naga-ext")]
206            Type::RayQuery(Some(tags)) => {
207                write!(f, "ray_query<")?;
208                for (index, tag) in tags.tags().iter().enumerate() {
209                    if index > 0 {
210                        write!(f, ", ")?;
211                    }
212                    write!(f, "{tag}")?;
213                }
214                write!(f, ">")?;
215                Ok(())
216            }
217            #[cfg(feature = "naga-ext")]
218            Type::AccelerationStructure(None) => write!(f, "acceleration_structure"),
219            #[cfg(feature = "naga-ext")]
220            Type::AccelerationStructure(Some(tags)) => {
221                write!(f, "acceleration_structure<")?;
222                for (index, tag) in tags.tags().iter().enumerate() {
223                    if index > 0 {
224                        write!(f, ", ")?;
225                    }
226                    write!(f, "{tag}")?;
227                }
228                write!(f, ">")?;
229                Ok(())
230            }
231        }
232    }
233}
234
235impl Display for TextureType {
236    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237        match self {
238            TextureType::Sampled1D(sampled) => write!(f, "texture_1d<{sampled}>"),
239            TextureType::Sampled2D(sampled) => write!(f, "texture_2d<{sampled}>"),
240            TextureType::Sampled2DArray(sampled) => write!(f, "texture_2d_array<{sampled}>"),
241            TextureType::Sampled3D(sampled) => write!(f, "texture_3d<{sampled}>"),
242            TextureType::SampledCube(sampled) => write!(f, "texture_cube<{sampled}>"),
243            TextureType::SampledCubeArray(sampled) => write!(f, "texture_cube_array<{sampled}>"),
244            TextureType::Multisampled2D(sampled) => write!(f, "texture_multisampled_2d<{sampled}>"),
245            TextureType::DepthMultisampled2D => write!(f, "texture_depth_multisampled_2d"),
246            TextureType::External => write!(f, "texture_external<>"),
247            TextureType::Storage1D(texel, access) => {
248                write!(f, "texture_storage_1d<{texel}, {access}>")
249            }
250            TextureType::Storage2D(texel, access) => {
251                write!(f, "texture_storage_2d<{texel}, {access}>")
252            }
253            TextureType::Storage2DArray(texel, access) => {
254                write!(f, "texture_storage_2d_array<{texel}, {access}>")
255            }
256            TextureType::Storage3D(texel, access) => {
257                write!(f, "texture_storage_3d<{texel}, {access}>")
258            }
259            TextureType::Depth2D => write!(f, "texture_depth_2d"),
260            TextureType::Depth2DArray => write!(f, "texture_depth_2d_array"),
261            TextureType::DepthCube => write!(f, "texture_depth_cube"),
262            TextureType::DepthCubeArray => write!(f, "texture_depth_cube_array"),
263            #[cfg(feature = "naga-ext")]
264            TextureType::Sampled1DArray(sampled) => write!(f, "texture_1d_array<{sampled}>"),
265            #[cfg(feature = "naga-ext")]
266            TextureType::Storage1DArray(texel, access) => {
267                write!(f, "texture_storage_1d_array<{texel}, {access}>")
268            }
269            #[cfg(feature = "naga-ext")]
270            TextureType::Multisampled2DArray(sampled) => {
271                write!(f, "texture_multisampled_2d_array<{sampled}>")
272            }
273        }
274    }
275}
276
277impl Display for SamplerType {
278    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
279        match self {
280            SamplerType::Sampler => write!(f, "sampler"),
281            SamplerType::SamplerComparison => write!(f, "sampler_comparison"),
282        }
283    }
284}