1use crate::{span::Spanned, syntax::*};
2use core::fmt;
3use std::fmt::{Display, Formatter};
4
5use itertools::Itertools;
6
7struct FormatFn<F: (Fn(&mut Formatter) -> fmt::Result)>(F);
9
10impl<F: Fn(&mut Formatter) -> fmt::Result> Display for FormatFn<F> {
11 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
12 (self.0)(f)
13 }
14}
15
16impl<T: Display> Display for Spanned<T> {
17 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
18 self.node().fmt(f)
19 }
20}
21
22struct Indent<T: Display>(pub T);
23
24impl<T: Display> Display for Indent<T> {
25 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
26 let indent = " ";
27 let inner_display = self.0.to_string();
28 let fmt = inner_display
29 .lines()
30 .format_with("\n", |l, f| f(&format_args!("{indent}{l}")));
31 write!(f, "{fmt}")?;
32 Ok(())
33 }
34}
35
36impl Display for TranslationUnit {
37 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
38 #[cfg(feature = "imports")]
39 if !self.imports.is_empty() {
40 for import in &self.imports {
41 writeln!(f, "import {import}\n")?;
42 }
43 }
44 if !self.global_directives.is_empty() {
45 let directives = self.global_directives.iter().format("\n");
46 write!(f, "{directives}\n\n")?;
47 }
48 let declarations = self
49 .global_declarations
50 .iter()
51 .filter(|decl| !matches!(decl.node(), GlobalDeclaration::Void))
52 .format("\n\n");
53 writeln!(f, "{declarations}")
54 }
55}
56
57impl Display for Ident {
58 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
59 write!(f, "{}", self.name())
60 }
61}
62
63#[cfg(feature = "imports")]
64impl Display for ImportStatement {
65 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
66 #[cfg(feature = "attributes")]
67 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
68 if let Some(path) = &self.path {
69 write!(f, "{path}::")?;
70 }
71 let content = &self.content;
72 write!(f, "{content};")
73 }
74}
75
76#[cfg(feature = "imports")]
77impl Display for ModulePath {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 match &self.origin {
80 PathOrigin::Absolute => write!(f, "package")?,
81 PathOrigin::Relative(0) => write!(f, "self")?,
82 PathOrigin::Relative(n) => write!(f, "{}", (0..*n).map(|_| "super").format("::"))?,
83 PathOrigin::Package(p) => write!(f, "{p}")?,
84 };
85 if !self.components.is_empty() {
86 write!(f, "::{}", self.components.iter().format("::"))?;
87 }
88 Ok(())
89 }
90}
91
92#[cfg(feature = "imports")]
93impl Display for Import {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 if !self.path.is_empty() {
96 let path = self.path.iter().format("::");
97 write!(f, "{path}::")?;
98 }
99 let content = &self.content;
100 write!(f, "{content}")
101 }
102}
103
104#[cfg(feature = "imports")]
105impl Display for ImportContent {
106 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
107 match self {
108 ImportContent::Item(item) => {
109 write!(f, "{}", item.ident)?;
110 if let Some(rename) = &item.rename {
111 write!(f, " as {rename}")?;
112 }
113 Ok(())
114 }
115 ImportContent::Collection(coll) => {
116 let coll = coll.iter().format(", ");
117 write!(f, "{{ {coll} }}")
118 }
119 }
120 }
121}
122
123impl Display for GlobalDirective {
124 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
125 match self {
126 GlobalDirective::Diagnostic(print) => write!(f, "{print}"),
127 GlobalDirective::Enable(print) => write!(f, "{print}"),
128 GlobalDirective::Requires(print) => write!(f, "{print}"),
129 }
130 }
131}
132
133impl Display for DiagnosticDirective {
134 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
135 #[cfg(feature = "attributes")]
136 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
137 let severity = &self.severity;
138 let rule = &self.rule_name;
139 write!(f, "diagnostic ({severity}, {rule});")
140 }
141}
142
143impl Display for DiagnosticSeverity {
144 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
145 match self {
146 Self::Error => write!(f, "error"),
147 Self::Warning => write!(f, "warning"),
148 Self::Info => write!(f, "info"),
149 Self::Off => write!(f, "off"),
150 }
151 }
152}
153
154impl Display for EnableDirective {
155 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
156 #[cfg(feature = "attributes")]
157 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
158 let exts = self.extensions.iter().format(", ");
159 write!(f, "enable {exts};")
160 }
161}
162
163impl Display for RequiresDirective {
164 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
165 #[cfg(feature = "attributes")]
166 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
167 let exts = self.extensions.iter().format(", ");
168 write!(f, "requires {exts};")
169 }
170}
171
172impl Display for GlobalDeclaration {
173 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
174 match self {
175 GlobalDeclaration::Void => write!(f, ";"),
176 GlobalDeclaration::Declaration(print) => write!(f, "{print}"),
177 GlobalDeclaration::TypeAlias(print) => write!(f, "{print}"),
178 GlobalDeclaration::Struct(print) => write!(f, "{print}"),
179 GlobalDeclaration::Function(print) => write!(f, "{print}"),
180 GlobalDeclaration::ConstAssert(print) => write!(f, "{print}"),
181 }
182 }
183}
184
185impl Display for Declaration {
186 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
187 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
188 let kind = &self.kind;
189 let name = &self.ident;
190 let ty = self
191 .ty
192 .iter()
193 .format_with("", |ty, f| f(&format_args!(": {ty}")));
194 let init = self
195 .initializer
196 .iter()
197 .format_with("", |ty, f| f(&format_args!(" = {ty}")));
198 write!(f, "{kind} {name}{ty}{init};")
199 }
200}
201
202impl Display for DeclarationKind {
203 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
204 match self {
205 Self::Const => write!(f, "const"),
206 Self::Override => write!(f, "override"),
207 Self::Let => write!(f, "let"),
208 Self::Var(addr_space) => match addr_space {
209 Some(addr_space) => write!(f, "var<{addr_space}>"),
210 None => write!(f, "var"),
211 },
212 }
213 }
214}
215
216impl Display for AddressSpace {
217 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
218 match self {
219 Self::Function => write!(f, "function"),
220 Self::Private => write!(f, "private"),
221 Self::Workgroup => write!(f, "workgroup"),
222 Self::Uniform => write!(f, "uniform"),
223 Self::Storage(access_mode) => match access_mode {
224 Some(access_mode) => write!(f, "storage, {access_mode}"),
225 None => write!(f, "storage"),
226 },
227 Self::Handle => write!(f, "handle"),
228 #[cfg(feature = "push_constant")]
229 Self::PushConstant => write!(f, "push_constant"),
230 }
231 }
232}
233
234impl Display for AccessMode {
235 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
236 match self {
237 Self::Read => write!(f, "read"),
238 Self::Write => write!(f, "write"),
239 Self::ReadWrite => write!(f, "read_write"),
240 }
241 }
242}
243
244impl Display for TypeAlias {
245 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
246 #[cfg(feature = "attributes")]
247 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
248 let name = &self.ident;
249 let ty = &self.ty;
250 write!(f, "alias {name} = {ty};")
251 }
252}
253
254impl Display for Struct {
255 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
256 #[cfg(feature = "attributes")]
257 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
258 let name = &self.ident;
259 let members = Indent(self.members.iter().format(",\n"));
260 write!(f, "struct {name} {{\n{members}\n}}")
261 }
262}
263
264impl Display for StructMember {
265 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
266 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
267 let name = &self.ident;
268 let ty = &self.ty;
269 write!(f, "{name}: {ty}")
270 }
271}
272
273impl Display for Function {
274 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
275 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
276 let name = &self.ident;
277 let params = self.parameters.iter().format(", ");
278 let ret_ty = self.return_type.iter().format_with("", |ty, f| {
279 f(&FormatFn(|f: &mut Formatter| {
280 write!(f, "-> ")?;
281 write!(f, "{}", fmt_attrs(&self.return_attributes, true))?;
282 write!(f, "{ty} ")?;
283 Ok(())
284 }))
285 });
286 let body = &self.body;
287 write!(f, "fn {name}({params}) {ret_ty}{body}")
288 }
289}
290
291impl Display for FormalParameter {
292 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
293 write!(f, "{}", fmt_attrs(&self.attributes, true))?;
294 let name = &self.ident;
295 let ty = &self.ty;
296 write!(f, "{name}: {ty}")
297 }
298}
299
300impl Display for ConstAssert {
301 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
302 #[cfg(feature = "attributes")]
303 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
304 let expr = &self.expression;
305 write!(f, "const_assert {expr};",)
306 }
307}
308
309impl Display for BuiltinValue {
310 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
311 match self {
312 Self::VertexIndex => write!(f, "vertex_index"),
313 Self::InstanceIndex => write!(f, "instance_index"),
314 Self::ClipDistances => write!(f, "clip_distances"),
315 Self::Position => write!(f, "position"),
316 Self::FrontFacing => write!(f, "front_facing"),
317 Self::FragDepth => write!(f, "frag_depth"),
318 Self::SampleIndex => write!(f, "sample_index"),
319 Self::SampleMask => write!(f, "sample_mask"),
320 Self::LocalInvocationId => write!(f, "local_invocation_id"),
321 Self::LocalInvocationIndex => write!(f, "local_invocation_index"),
322 Self::GlobalInvocationId => write!(f, "global_invocation_id"),
323 Self::WorkgroupId => write!(f, "workgroup_id"),
324 Self::NumWorkgroups => write!(f, "num_workgroups"),
325 Self::SubgroupInvocationId => write!(f, "subgroup_invocation_id"),
326 Self::SubgroupSize => write!(f, "subgroup_size"),
327 #[cfg(feature = "naga_ext")]
328 Self::PrimitiveIndex => write!(f, "primitive_index"),
329 #[cfg(feature = "naga_ext")]
330 Self::ViewIndex => write!(f, "view_index"),
331 }
332 }
333}
334
335impl Display for InterpolationType {
336 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
337 match self {
338 InterpolationType::Perspective => write!(f, "perspective"),
339 InterpolationType::Linear => write!(f, "linear"),
340 InterpolationType::Flat => write!(f, "flat"),
341 }
342 }
343}
344
345impl Display for InterpolationSampling {
346 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
347 match self {
348 Self::Center => write!(f, "center"),
349 Self::Centroid => write!(f, "centroid"),
350 Self::Sample => write!(f, "sample"),
351 Self::First => write!(f, "first"),
352 Self::Either => write!(f, "either"),
353 }
354 }
355}
356
357#[cfg(feature = "naga_ext")]
358impl Display for ConservativeDepth {
359 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
360 match self {
361 Self::GreaterEqual => write!(f, "Greater_equal"),
362 Self::LessEqual => write!(f, "less_equal"),
363 Self::Unchanged => write!(f, "unchanged"),
364 }
365 }
366}
367
368impl Display for Attribute {
369 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
370 match self {
371 Attribute::Align(e1) => write!(f, "@align({e1})"),
372 Attribute::Binding(e1) => write!(f, "@binding({e1})"),
373 Attribute::BlendSrc(e1) => write!(f, "@blend_src({e1})"),
374 Attribute::Builtin(e1) => write!(f, "@builtin({e1})"),
375 Attribute::Const => write!(f, "@const"),
376 Attribute::Diagnostic(DiagnosticAttribute { severity, rule }) => {
377 write!(f, "@diagnostic({severity}, {rule})")
378 }
379 Attribute::Group(e1) => write!(f, "@group({e1})"),
380 Attribute::Id(e1) => write!(f, "@id({e1})"),
381 Attribute::Interpolate(InterpolateAttribute { ty, sampling }) => {
382 if let Some(sampling) = sampling {
383 write!(f, "@interpolate({ty}, {sampling})")
384 } else {
385 write!(f, "@interpolate({ty})")
386 }
387 }
388 Attribute::Invariant => write!(f, "@invariant"),
389 Attribute::Location(e1) => write!(f, "@location({e1})"),
390 Attribute::MustUse => write!(f, "@must_use"),
391 Attribute::Size(e1) => write!(f, "@size({e1})"),
392 Attribute::WorkgroupSize(WorkgroupSizeAttribute { x, y, z }) => {
393 let xyz = std::iter::once(x).chain(y).chain(z).format(", ");
394 write!(f, "@workgroup_size({xyz})")
395 }
396 Attribute::Vertex => write!(f, "@vertex"),
397 Attribute::Fragment => write!(f, "@fragment"),
398 Attribute::Compute => write!(f, "@compute"),
399 #[cfg(feature = "imports")]
400 Attribute::Publish => write!(f, "@publish"),
401 #[cfg(feature = "condcomp")]
402 Attribute::If(e1) => write!(f, "@if({e1})"),
403 #[cfg(feature = "condcomp")]
404 Attribute::Elif(e1) => write!(f, "@elif({e1})"),
405 #[cfg(feature = "condcomp")]
406 Attribute::Else => write!(f, "@else"),
407 #[cfg(feature = "generics")]
408 Attribute::Type(e1) => write!(f, "@type({e1})"),
409 #[cfg(feature = "naga_ext")]
410 Attribute::EarlyDepthTest(None) => write!(f, "@early_depth_test"),
411 #[cfg(feature = "naga_ext")]
412 Attribute::EarlyDepthTest(Some(e1)) => write!(f, "@early_depth_test({e1})"),
413 Attribute::Custom(custom) => {
414 let name = &custom.name;
415 let args = custom.arguments.iter().format_with("", |args, f| {
416 f(&format_args!("({})", args.iter().format(", ")))
417 });
418 write!(f, "@{name}{args}")
419 }
420 }
421 }
422}
423
424#[cfg(feature = "generics")]
425impl Display for TypeConstraint {
426 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
427 let name = &self.ident;
428 let variants = self.variants.iter().format(" | ");
429 write!(f, "{name}, {variants}")
430 }
431}
432
433fn fmt_attrs(attrs: &[AttributeNode], inline: bool) -> impl fmt::Display + '_ {
434 FormatFn(move |f| {
435 let print = attrs.iter().format(" ");
436 let suffix = if attrs.is_empty() {
437 ""
438 } else if inline {
439 " "
440 } else {
441 "\n"
442 };
443 write!(f, "{print}{suffix}")
444 })
445}
446
447impl Display for Expression {
448 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
449 match self {
450 Expression::Literal(print) => write!(f, "{print}"),
451 Expression::Parenthesized(print) => {
452 write!(f, "{print}")
453 }
454 Expression::NamedComponent(print) => write!(f, "{print}"),
455 Expression::Indexing(print) => write!(f, "{print}"),
456 Expression::Unary(print) => write!(f, "{print}"),
457 Expression::Binary(print) => write!(f, "{print}"),
458 Expression::FunctionCall(print) => write!(f, "{print}"),
459 Expression::TypeOrIdentifier(print) => write!(f, "{print}"),
460 }
461 }
462}
463
464impl Display for LiteralExpression {
465 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
466 match self {
467 LiteralExpression::Bool(true) => write!(f, "true"),
468 LiteralExpression::Bool(false) => write!(f, "false"),
469 LiteralExpression::AbstractInt(num) => write!(f, "{num}"),
470 LiteralExpression::AbstractFloat(num) => write!(f, "{num:?}"), LiteralExpression::I32(num) => write!(f, "{num}i"),
472 LiteralExpression::U32(num) => write!(f, "{num}u"),
473 LiteralExpression::F32(num) => write!(f, "{num}f"),
474 LiteralExpression::F16(num) => write!(f, "{num}h"),
475 #[cfg(feature = "naga_ext")]
476 LiteralExpression::I64(num) => write!(f, "{num}li"),
477 #[cfg(feature = "naga_ext")]
478 LiteralExpression::U64(num) => write!(f, "{num}lu"),
479 #[cfg(feature = "naga_ext")]
480 LiteralExpression::F64(num) => write!(f, "{num}lf"),
481 }
482 }
483}
484
485impl Display for ParenthesizedExpression {
486 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
487 let expr = &self.expression;
488 write!(f, "({expr})")
489 }
490}
491
492impl Display for NamedComponentExpression {
493 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
494 let base = &self.base;
495 let component = &self.component;
496 write!(f, "{base}.{component}")
497 }
498}
499
500impl Display for IndexingExpression {
501 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
502 let base = &self.base;
503 let index = &self.index;
504 write!(f, "{base}[{index}]")
505 }
506}
507
508impl Display for UnaryExpression {
509 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
510 let operator = &self.operator;
511 let operand = &self.operand;
512 write!(f, "{operator}{operand}")
513 }
514}
515
516impl Display for UnaryOperator {
517 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
518 match self {
519 UnaryOperator::LogicalNegation => write!(f, "!"),
520 UnaryOperator::Negation => write!(f, "-"),
521 UnaryOperator::BitwiseComplement => write!(f, "~"),
522 UnaryOperator::AddressOf => write!(f, "&"),
523 UnaryOperator::Indirection => write!(f, "*"),
524 }
525 }
526}
527
528impl Display for BinaryExpression {
529 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
530 let operator = &self.operator;
531 let left = &self.left;
532 let right = &self.right;
533 write!(f, "{left} {operator} {right}")
534 }
535}
536
537impl Display for BinaryOperator {
538 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
539 match self {
540 BinaryOperator::ShortCircuitOr => write!(f, "||"),
541 BinaryOperator::ShortCircuitAnd => write!(f, "&&"),
542 BinaryOperator::Addition => write!(f, "+"),
543 BinaryOperator::Subtraction => write!(f, "-"),
544 BinaryOperator::Multiplication => write!(f, "*"),
545 BinaryOperator::Division => write!(f, "/"),
546 BinaryOperator::Remainder => write!(f, "%"),
547 BinaryOperator::Equality => write!(f, "=="),
548 BinaryOperator::Inequality => write!(f, "!="),
549 BinaryOperator::LessThan => write!(f, "<"),
550 BinaryOperator::LessThanEqual => write!(f, "<="),
551 BinaryOperator::GreaterThan => write!(f, ">"),
552 BinaryOperator::GreaterThanEqual => write!(f, ">="),
553 BinaryOperator::BitwiseOr => write!(f, "|"),
554 BinaryOperator::BitwiseAnd => write!(f, "&"),
555 BinaryOperator::BitwiseXor => write!(f, "^"),
556 BinaryOperator::ShiftLeft => write!(f, "<<"),
557 BinaryOperator::ShiftRight => write!(f, ">>"),
558 }
559 }
560}
561
562impl Display for FunctionCall {
563 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
564 let ty = &self.ty;
565 let args = self.arguments.iter().format(", ");
566 write!(f, "{ty}({args})")
567 }
568}
569
570impl Display for TypeExpression {
571 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
572 let name = &self.ident;
573 let tplt = fmt_template(&self.template_args);
574 write!(f, "{name}{tplt}")
575 }
576}
577
578impl Display for TemplateArg {
579 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
580 let expr = &self.expression;
581 write!(f, "{expr}")
582 }
583}
584
585fn fmt_template(tplt: &Option<Vec<TemplateArg>>) -> impl fmt::Display + '_ {
586 tplt.iter().format_with("", |tplt, f| {
587 f(&format_args!("<{}>", tplt.iter().format(", ")))
588 })
589}
590
591impl Display for Statement {
592 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
593 match self {
594 Statement::Void => write!(f, ";"),
595 Statement::Compound(print) => write!(f, "{print}"),
596 Statement::Assignment(print) => write!(f, "{print}"),
597 Statement::Increment(print) => write!(f, "{print}"),
598 Statement::Decrement(print) => write!(f, "{print}"),
599 Statement::If(print) => write!(f, "{print}"),
600 Statement::Switch(print) => write!(f, "{print}"),
601 Statement::Loop(print) => write!(f, "{print}"),
602 Statement::For(print) => write!(f, "{print}"),
603 Statement::While(print) => write!(f, "{print}"),
604 Statement::Break(print) => write!(f, "{print}"),
605 Statement::Continue(print) => write!(f, "{print}"),
606 Statement::Return(print) => write!(f, "{print}"),
607 Statement::Discard(print) => write!(f, "{print}"),
608 Statement::FunctionCall(print) => write!(f, "{print}"),
609 Statement::ConstAssert(print) => write!(f, "{print}"),
610 Statement::Declaration(print) => write!(f, "{print}"),
611 }
612 }
613}
614
615impl Display for CompoundStatement {
616 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
617 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
618 let stmts = Indent(
619 self.statements
620 .iter()
621 .filter(|stmt| !matches!(stmt.node(), Statement::Void))
622 .format("\n"),
623 );
624 write!(f, "{{\n{stmts}\n}}")
625 }
626}
627
628impl Display for AssignmentStatement {
629 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
630 #[cfg(feature = "attributes")]
631 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
632 let operator = &self.operator;
633 let lhs = &self.lhs;
634 let rhs = &self.rhs;
635 write!(f, "{lhs} {operator} {rhs};")
636 }
637}
638
639impl Display for AssignmentOperator {
640 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
641 match self {
642 AssignmentOperator::Equal => write!(f, "="),
643 AssignmentOperator::PlusEqual => write!(f, "+="),
644 AssignmentOperator::MinusEqual => write!(f, "-="),
645 AssignmentOperator::TimesEqual => write!(f, "*="),
646 AssignmentOperator::DivisionEqual => write!(f, "/="),
647 AssignmentOperator::ModuloEqual => write!(f, "%="),
648 AssignmentOperator::AndEqual => write!(f, "&="),
649 AssignmentOperator::OrEqual => write!(f, "|="),
650 AssignmentOperator::XorEqual => write!(f, "^="),
651 AssignmentOperator::ShiftRightAssign => write!(f, ">>="),
652 AssignmentOperator::ShiftLeftAssign => write!(f, "<<="),
653 }
654 }
655}
656
657impl Display for IncrementStatement {
658 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
659 #[cfg(feature = "attributes")]
660 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
661 let expr = &self.expression;
662 write!(f, "{expr}++;")
663 }
664}
665
666impl Display for DecrementStatement {
667 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
668 #[cfg(feature = "attributes")]
669 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
670 let expr = &self.expression;
671 write!(f, "{expr}--;")
672 }
673}
674
675impl Display for IfStatement {
676 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
677 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
678 let if_clause = &self.if_clause;
679 write!(f, "{if_clause}")?;
680 for else_if_clause in self.else_if_clauses.iter() {
681 write!(f, "\n{else_if_clause}")?;
682 }
683 if let Some(else_clause) = &self.else_clause {
684 write!(f, "\n{else_clause}")?;
685 }
686 Ok(())
687 }
688}
689
690impl Display for IfClause {
691 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
692 let expr = &self.expression;
693 let stmt = &self.body;
694 write!(f, "if {expr} {stmt}")
695 }
696}
697
698impl Display for ElseIfClause {
699 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
700 #[cfg(feature = "attributes")]
701 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
702 let expr = &self.expression;
703 let stmt = &self.body;
704 write!(f, "else if {expr} {stmt}")
705 }
706}
707
708impl Display for ElseClause {
709 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
710 #[cfg(feature = "attributes")]
711 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
712 let stmt = &self.body;
713 write!(f, "else {stmt}")
714 }
715}
716
717impl Display for SwitchStatement {
718 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
719 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
720 let expr = &self.expression;
721 let body_attrs = fmt_attrs(&self.body_attributes, false);
722 let clauses = Indent(self.clauses.iter().format("\n"));
723 write!(f, "switch {expr} {body_attrs}{{\n{clauses}\n}}")
724 }
725}
726
727impl Display for SwitchClause {
728 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
729 #[cfg(feature = "attributes")]
730 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
731 let cases = self.case_selectors.iter().format(", ");
732 let body = &self.body;
733 write!(f, "case {cases} {body}")
734 }
735}
736
737impl Display for CaseSelector {
738 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
739 match self {
740 CaseSelector::Default => write!(f, "default"),
741 CaseSelector::Expression(expr) => {
742 write!(f, "{expr}")
743 }
744 }
745 }
746}
747
748impl Display for LoopStatement {
749 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
750 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
751 let body_attrs = fmt_attrs(&self.body.attributes, false);
752 let stmts = Indent(
753 self.body
754 .statements
755 .iter()
756 .filter(|stmt| !matches!(stmt.node(), Statement::Void))
757 .format("\n"),
758 );
759 let continuing = self
760 .continuing
761 .iter()
762 .format_with("", |cont, f| f(&format_args!("{}\n", Indent(cont))));
763 write!(f, "loop {body_attrs}{{\n{stmts}\n{continuing}}}")
764 }
765}
766
767impl Display for ContinuingStatement {
768 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
769 #[cfg(feature = "attributes")]
770 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
771 let body_attrs = fmt_attrs(&self.body.attributes, false);
772 let stmts = Indent(
773 self.body
774 .statements
775 .iter()
776 .filter(|stmt| !matches!(stmt.node(), Statement::Void))
777 .format("\n"),
778 );
779 let break_if = self
780 .break_if
781 .iter()
782 .format_with("", |stmt, f| f(&format_args!("{}\n", Indent(stmt))));
783 write!(f, "continuing {body_attrs}{{\n{stmts}\n{break_if}}}")
784 }
785}
786
787impl Display for BreakIfStatement {
788 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
789 #[cfg(feature = "attributes")]
790 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
791 let expr = &self.expression;
792 write!(f, "break if {expr};")
793 }
794}
795
796impl Display for ForStatement {
797 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
798 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
799 let mut init = self
800 .initializer
801 .as_ref()
802 .map(|stmt| format!("{stmt}"))
803 .unwrap_or_default();
804 if init.ends_with(';') {
805 init.pop();
806 }
807 let cond = self
808 .condition
809 .iter()
810 .format_with("", |expr, f| f(&format_args!("{expr}")));
811 let mut updt = self
812 .update
813 .as_ref()
814 .map(|stmt| format!("{stmt}"))
815 .unwrap_or_default();
816 if updt.ends_with(';') {
817 updt.pop();
818 }
819 let body = &self.body;
820 write!(f, "for ({init}; {cond}; {updt}) {body}")
821 }
822}
823
824impl Display for WhileStatement {
825 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
826 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
827 let cond = &self.condition;
828 let body = &self.body;
829 write!(f, "while ({cond}) {body}")
830 }
831}
832
833impl Display for BreakStatement {
834 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
835 #[cfg(feature = "attributes")]
836 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
837 write!(f, "break;")
838 }
839}
840
841impl Display for ContinueStatement {
842 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
843 #[cfg(feature = "attributes")]
844 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
845 write!(f, "continue;")
846 }
847}
848
849impl Display for ReturnStatement {
850 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
851 #[cfg(feature = "attributes")]
852 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
853 let expr = self
854 .expression
855 .iter()
856 .format_with("", |expr, f| f(&format_args!(" {expr}")));
857 write!(f, "return{expr};")
858 }
859}
860
861impl Display for DiscardStatement {
862 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
863 #[cfg(feature = "attributes")]
864 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
865 write!(f, "discard;")
866 }
867}
868
869impl Display for FunctionCallStatement {
870 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
871 #[cfg(feature = "attributes")]
872 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
873 let call = &self.call;
874 write!(f, "{call};")
875 }
876}