Skip to content

Commit cd8eb6f

Browse files
committed
Add option to vertically align enum discriminants.
1 parent 8298f25 commit cd8eb6f

File tree

5 files changed

+134
-3
lines changed

5 files changed

+134
-3
lines changed

Configurations.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,52 @@ impl Lorem {
867867
See also [`brace_style`](#brace_style), [`control_brace_style`](#control_brace_style).
868868

869869

870+
## `enum_discrim_align_threshold`
871+
872+
The maximum diff of width between enum variants to have discriminants aligned with each other.
873+
Variants without discriminants would be ignored for the purpose of alignment.
874+
875+
- **Default value** : 0
876+
- **Possible values**: any positive integer
877+
- **Stable**: No
878+
879+
#### `0` (default):
880+
881+
```rust
882+
enum Foo {
883+
A = 0,
884+
Bb = 1,
885+
RandomLongVariantWithoutDiscriminant,
886+
Ccc = 71,
887+
}
888+
889+
enum Bar {
890+
A = 0,
891+
Bb = 1,
892+
ThisOneisWithDiscriminantAndPreventsAlignment = 10,
893+
Ccc = 71,
894+
}
895+
```
896+
897+
#### `20`:
898+
899+
```rust
900+
enum Foo {
901+
A = 0,
902+
Bb = 1,
903+
RandomLongVariantWithoutDiscriminant,
904+
Ccc = 2,
905+
}
906+
907+
enum Bar {
908+
A = 0,
909+
Bb = 1,
910+
ThisOneisWithDiscriminantAndPreventsAlignment = 10,
911+
Ccc = 71,
912+
}
913+
```
914+
915+
870916
## `fn_single_line`
871917

872918
Put single-expression functions on a single line

src/config/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ create_config! {
8686
combine_control_expr: bool, true, false, "Combine control expressions with function calls.";
8787
struct_field_align_threshold: usize, 0, false, "Align struct fields if their diffs fits within \
8888
threshold.";
89+
enum_discrim_align_threshold: usize, 0, false,
90+
"Align enum variants discrims, if their diffs fit within threshold";
8991
match_arm_blocks: bool, true, false, "Wrap the body of arms in blocks when it does not fit on \
9092
the same line with the pattern of arms";
9193
force_multiline_blocks: bool, false, false,

src/items.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,24 @@ impl<'a> FmtVisitor<'a> {
494494
let original_offset = self.block_indent;
495495
self.block_indent = self.block_indent.block_indent(self.config);
496496

497+
// If enum variants have discriminants, try to vertically align those,
498+
// provided it does not result in too much padding
499+
let pad_discrim_ident_to;
500+
let diff_threshold = self.config.enum_discrim_align_threshold();
501+
let discr_ident_lens: Vec<_> = enum_def
502+
.variants
503+
.iter()
504+
.filter(|var| var.node.disr_expr.is_some())
505+
.map(|var| rewrite_ident(&self.get_context(), var.node.ident).len())
506+
.collect();
507+
let shortest_w_discr = *discr_ident_lens.iter().min().unwrap_or(&0);
508+
let longest_w_discr = *discr_ident_lens.iter().max().unwrap_or(&0);
509+
if longest_w_discr > shortest_w_discr + diff_threshold {
510+
pad_discrim_ident_to = 0;
511+
} else {
512+
pad_discrim_ident_to = longest_w_discr;
513+
}
514+
497515
let itemize_list_with = |one_line_width: usize| {
498516
itemize_list(
499517
self.snippet_provider,
@@ -508,7 +526,7 @@ impl<'a> FmtVisitor<'a> {
508526
}
509527
},
510528
|f| f.span.hi(),
511-
|f| self.format_variant(f, one_line_width),
529+
|f| self.format_variant(f, one_line_width, pad_discrim_ident_to),
512530
body_lo,
513531
body_hi,
514532
false,
@@ -544,7 +562,12 @@ impl<'a> FmtVisitor<'a> {
544562
}
545563

546564
// Variant of an enum.
547-
fn format_variant(&self, field: &ast::Variant, one_line_width: usize) -> Option<String> {
565+
fn format_variant(
566+
&self,
567+
field: &ast::Variant,
568+
one_line_width: usize,
569+
pad_discrim_ident_to: usize,
570+
) -> Option<String> {
548571
if contains_skip(&field.node.attrs) {
549572
let lo = field.node.attrs[0].span.lo();
550573
let span = mk_sp(lo, field.span.hi());
@@ -571,7 +594,11 @@ impl<'a> FmtVisitor<'a> {
571594
)?,
572595
ast::VariantData::Unit(..) => {
573596
if let Some(ref expr) = field.node.disr_expr {
574-
let lhs = format!("{} =", rewrite_ident(&context, field.node.ident));
597+
let lhs = format!(
598+
"{:1$} =",
599+
rewrite_ident(&context, field.node.ident),
600+
pad_discrim_ident_to
601+
);
575602
rewrite_assign_rhs(&context, lhs, &*expr.value, shape)?
576603
} else {
577604
rewrite_ident(&context, field.node.ident).to_owned()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// rustfmt-enum_discrim_align_threshold: 20
2+
3+
enum Standard {
4+
A = 1,
5+
Bcdef = 2,
6+
}
7+
8+
enum Mixed {
9+
ThisIsAFairlyLongEnumVariantWithoutDiscrim,
10+
A = 1,
11+
ThisIsAFairlyLongEnumVariantWithoutDiscrim2,
12+
Bcdef = 2,
13+
}
14+
15+
enum TooLong {
16+
ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaaaaaaaa = 10,
17+
A = 1,
18+
Bcdef = 2,
19+
}
20+
21+
// Live specimen from #1686
22+
enum LongWithSmallDiff {
23+
SceneColorimetryEstimates = 0x73636F65,
24+
SceneAppearanceEstimates = 0x73617065,
25+
FocalPlaneColorimetryEstimates = 0x66706365,
26+
ReflectionHardcopyOriginalColorimetry = 0x72686F63,
27+
ReflectionPrintOutputColorimetry = 0x72706F63,
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// rustfmt-enum_discrim_align_threshold: 20
2+
3+
enum Standard {
4+
A = 1,
5+
Bcdef = 2,
6+
}
7+
8+
enum Mixed {
9+
ThisIsAFairlyLongEnumVariantWithoutDiscrim,
10+
A = 1,
11+
ThisIsAFairlyLongEnumVariantWithoutDiscrim2,
12+
Bcdef = 2,
13+
}
14+
15+
enum TooLong {
16+
ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaaaaaaaa = 10,
17+
A = 1,
18+
Bcdef = 2,
19+
}
20+
21+
// Live specimen from #1686
22+
enum LongWithSmallDiff {
23+
SceneColorimetryEstimates = 0x73636F65,
24+
SceneAppearanceEstimates = 0x73617065,
25+
FocalPlaneColorimetryEstimates = 0x66706365,
26+
ReflectionHardcopyOriginalColorimetry = 0x72686F63,
27+
ReflectionPrintOutputColorimetry = 0x72706F63,
28+
}

0 commit comments

Comments
 (0)