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