From c506c41229314a9798461f74ab8e6b48919124a5 Mon Sep 17 00:00:00 2001 From: moxian Date: Fri, 29 Jun 2018 06:47:51 +0000 Subject: [PATCH] Add option to vertically align enum discriminants. Part of vertical-alignment effort of #1103. Fixes #1686 --- Configurations.md | 46 +++++++++++++++++++ src/config/mod.rs | 2 + src/items.rs | 33 +++++++++++-- .../enum_discrim_align_threshold/20.rs | 28 +++++++++++ .../enum_discrim_align_threshold/20.rs | 28 +++++++++++ 5 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 tests/source/configs/enum_discrim_align_threshold/20.rs create mode 100644 tests/target/configs/enum_discrim_align_threshold/20.rs diff --git a/Configurations.md b/Configurations.md index 21a8d300db3..84dd3c18351 100644 --- a/Configurations.md +++ b/Configurations.md @@ -867,6 +867,52 @@ impl Lorem { See also [`brace_style`](#brace_style), [`control_brace_style`](#control_brace_style). +## `enum_discrim_align_threshold` + +The maximum diff of width between enum variants to have discriminants aligned with each other. +Variants without discriminants would be ignored for the purpose of alignment. + +- **Default value** : 0 +- **Possible values**: any positive integer +- **Stable**: No + +#### `0` (default): + +```rust +enum Foo { + A = 0, + Bb = 1, + RandomLongVariantWithoutDiscriminant, + Ccc = 71, +} + +enum Bar { + A = 0, + Bb = 1, + ThisOneisWithDiscriminantAndPreventsAlignment = 10, + Ccc = 71, +} +``` + +#### `20`: + +```rust +enum Foo { + A = 0, + Bb = 1, + RandomLongVariantWithoutDiscriminant, + Ccc = 2, +} + +enum Bar { + A = 0, + Bb = 1, + ThisOneisWithDiscriminantAndPreventsAlignment = 10, + Ccc = 71, +} +``` + + ## `fn_single_line` Put single-expression functions on a single line diff --git a/src/config/mod.rs b/src/config/mod.rs index 71bdefeea79..3960eea8c57 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -86,6 +86,8 @@ create_config! { combine_control_expr: bool, true, false, "Combine control expressions with function calls."; struct_field_align_threshold: usize, 0, false, "Align struct fields if their diffs fits within \ threshold."; + enum_discrim_align_threshold: usize, 0, false, + "Align enum variants discrims, if their diffs fit within threshold"; match_arm_blocks: bool, true, false, "Wrap the body of arms in blocks when it does not fit on \ the same line with the pattern of arms"; force_multiline_blocks: bool, false, false, diff --git a/src/items.rs b/src/items.rs index fe638a17069..1462ff73d30 100644 --- a/src/items.rs +++ b/src/items.rs @@ -494,6 +494,24 @@ impl<'a> FmtVisitor<'a> { let original_offset = self.block_indent; self.block_indent = self.block_indent.block_indent(self.config); + // If enum variants have discriminants, try to vertically align those, + // provided it does not result in too much padding + let pad_discrim_ident_to; + let diff_threshold = self.config.enum_discrim_align_threshold(); + let discr_ident_lens: Vec<_> = enum_def + .variants + .iter() + .filter(|var| var.node.disr_expr.is_some()) + .map(|var| rewrite_ident(&self.get_context(), var.node.ident).len()) + .collect(); + let shortest_w_discr = *discr_ident_lens.iter().min().unwrap_or(&0); + let longest_w_discr = *discr_ident_lens.iter().max().unwrap_or(&0); + if longest_w_discr > shortest_w_discr + diff_threshold { + pad_discrim_ident_to = 0; + } else { + pad_discrim_ident_to = longest_w_discr; + } + let itemize_list_with = |one_line_width: usize| { itemize_list( self.snippet_provider, @@ -508,7 +526,7 @@ impl<'a> FmtVisitor<'a> { } }, |f| f.span.hi(), - |f| self.format_variant(f, one_line_width), + |f| self.format_variant(f, one_line_width, pad_discrim_ident_to), body_lo, body_hi, false, @@ -544,7 +562,12 @@ impl<'a> FmtVisitor<'a> { } // Variant of an enum. - fn format_variant(&self, field: &ast::Variant, one_line_width: usize) -> Option { + fn format_variant( + &self, + field: &ast::Variant, + one_line_width: usize, + pad_discrim_ident_to: usize, + ) -> Option { if contains_skip(&field.node.attrs) { let lo = field.node.attrs[0].span.lo(); let span = mk_sp(lo, field.span.hi()); @@ -571,7 +594,11 @@ impl<'a> FmtVisitor<'a> { )?, ast::VariantData::Unit(..) => { if let Some(ref expr) = field.node.disr_expr { - let lhs = format!("{} =", rewrite_ident(&context, field.node.ident)); + let lhs = format!( + "{:1$} =", + rewrite_ident(&context, field.node.ident), + pad_discrim_ident_to + ); rewrite_assign_rhs(&context, lhs, &*expr.value, shape)? } else { rewrite_ident(&context, field.node.ident).to_owned() diff --git a/tests/source/configs/enum_discrim_align_threshold/20.rs b/tests/source/configs/enum_discrim_align_threshold/20.rs new file mode 100644 index 00000000000..d619d17922a --- /dev/null +++ b/tests/source/configs/enum_discrim_align_threshold/20.rs @@ -0,0 +1,28 @@ +// rustfmt-enum_discrim_align_threshold: 20 + +enum Standard { + A = 1, + Bcdef = 2, +} + +enum Mixed { + ThisIsAFairlyLongEnumVariantWithoutDiscrim, + A = 1, + ThisIsAFairlyLongEnumVariantWithoutDiscrim2, + Bcdef = 2, +} + +enum TooLong { + ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaaaaaaaa = 10, + A = 1, + Bcdef = 2, +} + +// Live specimen from #1686 +enum LongWithSmallDiff { + SceneColorimetryEstimates = 0x73636F65, + SceneAppearanceEstimates = 0x73617065, + FocalPlaneColorimetryEstimates = 0x66706365, + ReflectionHardcopyOriginalColorimetry = 0x72686F63, + ReflectionPrintOutputColorimetry = 0x72706F63, +} \ No newline at end of file diff --git a/tests/target/configs/enum_discrim_align_threshold/20.rs b/tests/target/configs/enum_discrim_align_threshold/20.rs new file mode 100644 index 00000000000..06d621a34cc --- /dev/null +++ b/tests/target/configs/enum_discrim_align_threshold/20.rs @@ -0,0 +1,28 @@ +// rustfmt-enum_discrim_align_threshold: 20 + +enum Standard { + A = 1, + Bcdef = 2, +} + +enum Mixed { + ThisIsAFairlyLongEnumVariantWithoutDiscrim, + A = 1, + ThisIsAFairlyLongEnumVariantWithoutDiscrim2, + Bcdef = 2, +} + +enum TooLong { + ThisOneHasDiscrimAaaaaaaaaaaaaaaaaaaaaaaaaaaa = 10, + A = 1, + Bcdef = 2, +} + +// Live specimen from #1686 +enum LongWithSmallDiff { + SceneColorimetryEstimates = 0x73636F65, + SceneAppearanceEstimates = 0x73617065, + FocalPlaneColorimetryEstimates = 0x66706365, + ReflectionHardcopyOriginalColorimetry = 0x72686F63, + ReflectionPrintOutputColorimetry = 0x72706F63, +}