Skip to content

Commit eb6c925

Browse files
committed
1 parent 34f9ca2 commit eb6c925

File tree

9 files changed

+202
-7
lines changed

9 files changed

+202
-7
lines changed

Diff for: Configurations.md

+68-1
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,6 @@ impl Lorem {
573573

574574
See also [`brace_style`](#brace_style), [`control_brace_style`](#control_brace_style).
575575

576-
577576
## `enum_discrim_align_threshold`
578577

579578
The maximum length of enum variant having discriminant, that gets vertically aligned with others.
@@ -620,6 +619,74 @@ enum Bar {
620619
}
621620
```
622621

622+
## `enum_variant_layout`
623+
624+
Control the layout of enum variants.
625+
626+
- **Default value**: `"Tall"`
627+
- **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"`
628+
- **Stable**: No
629+
630+
#### `"Tall"` (default):
631+
632+
```rust
633+
enum MyType {
634+
A {
635+
field1: bool,
636+
field2: bool,
637+
},
638+
#[something]
639+
B {
640+
field1: bool,
641+
field2: bool,
642+
},
643+
}
644+
645+
enum T {
646+
A { fieldA: T },
647+
B { fieldB: U },
648+
}
649+
```
650+
651+
#### `"Compressed"`
652+
653+
```rust
654+
enum MyType {
655+
A { field1: bool, field2: bool },
656+
#[something]
657+
B { field1: bool, field2: bool },
658+
}
659+
660+
enum T {
661+
A { fieldA: T },
662+
B { fieldB: U },
663+
}
664+
```
665+
666+
#### `"Vertical"`
667+
668+
```rust
669+
enum MyType {
670+
A {
671+
field1: bool,
672+
field2: bool,
673+
},
674+
#[something]
675+
B {
676+
field1: bool,
677+
field2: bool,
678+
},
679+
}
680+
681+
enum T {
682+
A {
683+
fieldA: T,
684+
},
685+
B {
686+
fieldB: U,
687+
},
688+
}
689+
```
623690

624691
## `error_on_line_overflow`
625692

Diff for: src/config/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ create_config! {
148148
"Write an item and its attribute on the same line \
149149
if their combined width is below a threshold";
150150
format_generated_files: bool, true, false, "Format generated files";
151+
enum_variant_layout: Density, Density::Tall, false,
152+
"Control the layout of enum variants";
151153

152154
// Options that can change the source code beyond whitespace/blocks (somewhat linty things)
153155
merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one";
@@ -667,6 +669,7 @@ edition = "2015"
667669
version = "One"
668670
inline_attribute_width = 0
669671
format_generated_files = true
672+
enum_variant_layout = "Tall"
670673
merge_derives = true
671674
use_try_shorthand = false
672675
use_field_init_shorthand = false

Diff for: src/items.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ use crate::comment::{
1414
recover_comment_removed, recover_missing_comment_in_span, rewrite_missing_comment,
1515
FindUncommented,
1616
};
17-
use crate::config::lists::*;
17+
use crate::config::{lists::*, Density};
1818
use crate::config::{BraceStyle, Config, IndentStyle, Version};
1919
use crate::expr::{
2020
is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with,
2121
rewrite_assign_rhs_with_comments, RhsAssignKind, RhsTactics,
2222
};
23-
use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
23+
use crate::lists::{
24+
definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
25+
};
2426
use crate::macros::{rewrite_macro, MacroPosition};
2527
use crate::overflow;
2628
use crate::rewrite::{Rewrite, RewriteContext};
@@ -515,11 +517,32 @@ impl<'a> FmtVisitor<'a> {
515517
};
516518
let mut items: Vec<_> = itemize_list_with(self.config.struct_variant_width());
517519

520+
let is_multiline_variant = |item: &ListItem| {
521+
item.inner_as_ref()
522+
.lines()
523+
.skip_while(|l| {
524+
if self.config.enum_variant_layout() == Density::Compressed {
525+
l.trim_start().starts_with("#") || l.trim_start().starts_with("///")
526+
} else {
527+
false
528+
}
529+
})
530+
.count()
531+
> 1
532+
};
533+
518534
// If one of the variants use multiple lines, use multi-lined formatting for all variants.
519-
let has_multiline_variant = items.iter().any(|item| item.inner_as_ref().contains('\n'));
520-
let has_single_line_variant = items.iter().any(|item| !item.inner_as_ref().contains('\n'));
521-
if has_multiline_variant && has_single_line_variant {
522-
items = itemize_list_with(0);
535+
let has_multiline_variant = items.iter().any(|item| is_multiline_variant(item));
536+
let has_single_line_variant = items
537+
.iter()
538+
.any(|item| item.inner_as_ref().lines().count() == 1);
539+
540+
match self.config.enum_variant_layout() {
541+
Density::Vertical => items = itemize_list_with(0),
542+
Density::Tall if has_multiline_variant && has_single_line_variant => {
543+
items = itemize_list_with(0)
544+
}
545+
_ => {}
523546
}
524547

525548
let shape = self.shape().sub_width(2)?;
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// rustfmt-enum_variant_layout: Compressed
2+
3+
pub enum MultiAndSingleLine {
4+
A { field1: () },
5+
#[attr]
6+
B { field1 : (), field2: (), },
7+
}
8+
9+
enum SingleLine {
10+
A { field: () },
11+
B { test: () },
12+
}
13+
14+
enum MyType {
15+
A { field1: bool, field2: bool },
16+
B { field1: bool, field2: bool },
17+
/// OMG a comment
18+
C { field1: bool, field2: bool },
19+
D { field1: bool, field2: bool },
20+
}

Diff for: tests/source/configs/enum_variant_layout/tall.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// rustfmt-enum_variant_layout: Tall
2+
3+
pub enum MultiAndSingleLine {
4+
A { field1: () },
5+
#[attr]
6+
B { field1 : (), field2: (), },
7+
}
8+
9+
enum SingleLine {
10+
A { field: () },
11+
B { test: () },
12+
}

Diff for: tests/source/configs/enum_variant_layout/vertical.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// rustfmt-enum_variant_layout: Vertical
2+
3+
pub enum MultiAndSingleLine {
4+
A { field1: () },
5+
#[attr]
6+
B { field1: (), field2: (), },
7+
}
8+
9+
enum SingleLine {
10+
A { field: () },
11+
B { test: () },
12+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// rustfmt-enum_variant_layout: Compressed
2+
3+
pub enum MultiAndSingleLine {
4+
A { field1: () },
5+
#[attr]
6+
B { field1: (), field2: () },
7+
}
8+
9+
enum SingleLine {
10+
A { field: () },
11+
B { test: () },
12+
}
13+
14+
enum MyType {
15+
A { field1: bool, field2: bool },
16+
B { field1: bool, field2: bool },
17+
/// OMG a comment
18+
C { field1: bool, field2: bool },
19+
D { field1: bool, field2: bool },
20+
}

Diff for: tests/target/configs/enum_variant_layout/tall.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// rustfmt-enum_variant_layout: Tall
2+
3+
pub enum MultiAndSingleLine {
4+
A {
5+
field1: (),
6+
},
7+
#[attr]
8+
B {
9+
field1: (),
10+
field2: (),
11+
},
12+
}
13+
14+
enum SingleLine {
15+
A { field: () },
16+
B { test: () },
17+
}

Diff for: tests/target/configs/enum_variant_layout/vertical.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// rustfmt-enum_variant_layout: Vertical
2+
3+
pub enum MultiAndSingleLine {
4+
A {
5+
field1: (),
6+
},
7+
#[attr]
8+
B {
9+
field1: (),
10+
field2: (),
11+
},
12+
}
13+
14+
enum SingleLine {
15+
A {
16+
field: (),
17+
},
18+
B {
19+
test: (),
20+
},
21+
}

0 commit comments

Comments
 (0)