Skip to content

Commit 7518f68

Browse files
committed
Add an option to format struct lits with either block or visual indent
1 parent e4a6f96 commit 7518f68

File tree

10 files changed

+185
-33
lines changed

10 files changed

+185
-33
lines changed

src/config.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
extern crate toml;
1212

13-
use {NewlineStyle, BraceStyle, ReturnIndent};
13+
use {NewlineStyle, BraceStyle, ReturnIndent, StructLitStyle};
1414
use lists::SeparatorTactic;
1515
use issues::ReportTactic;
1616

@@ -26,6 +26,7 @@ pub struct Config {
2626
pub fn_args_paren_newline: bool,
2727
pub struct_trailing_comma: SeparatorTactic,
2828
pub struct_lit_trailing_comma: SeparatorTactic,
29+
pub struct_lit_style: StructLitStyle,
2930
pub enum_trailing_comma: bool,
3031
pub report_todo: ReportTactic,
3132
pub report_fixme: ReportTactic,
@@ -35,6 +36,14 @@ pub struct Config {
3536
impl Config {
3637
pub fn from_toml(toml: &str) -> Config {
3738
let parsed = toml.parse().unwrap();
38-
toml::decode(parsed).unwrap()
39+
match toml::decode(parsed) {
40+
Some(decoded) => decoded,
41+
None => {
42+
println!("Decoding config file failed. Config:\n{}", toml);
43+
let parsed: toml::Value = toml.parse().unwrap();
44+
println!("\n\nParsed:\n{:?}", parsed);
45+
panic!();
46+
}
47+
}
3948
}
4049
}

src/default.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ fn_brace_style = "SameLineWhere"
77
fn_return_indent = "WithArgs"
88
fn_args_paren_newline = true
99
struct_trailing_comma = "Vertical"
10+
struct_lit_style = "BlockIndent"
1011
struct_lit_trailing_comma = "Vertical"
1112
enum_trailing_comma = true
1213
report_todo = "Always"

src/expr.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use rewrite::{Rewrite, RewriteContext};
1212
use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTactic};
1313
use string::{StringFormat, rewrite_string};
14+
use StructLitStyle;
1415
use utils::{span_after, make_indent};
1516
use visitor::FmtVisitor;
1617

@@ -188,8 +189,15 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
188189

189190
let path_str = pprust::path_to_string(path);
190191
// Foo { a: Foo } - indent is +3, width is -5.
191-
let indent = offset + path_str.len() + 3;
192-
let budget = width - (path_str.len() + 5);
192+
let (indent, budget) = match context.config.struct_lit_style {
193+
StructLitStyle::VisualIndent => {
194+
(offset + path_str.len() + 3, width - (path_str.len() + 5))
195+
}
196+
StructLitStyle::BlockIndent => {
197+
let indent = context.block_indent + context.config.tab_spaces;
198+
(indent, width - indent)
199+
}
200+
};
193201

194202
let field_iter = fields.into_iter().map(StructLitField::Regular)
195203
.chain(base.into_iter().map(StructLitField::Base));
@@ -243,12 +251,18 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
243251
v_width: budget,
244252
ends_with_newline: true, };
245253
let fields_str = write_list(&items, &fmt);
246-
Some(format!("{} {{ {} }}", path_str, fields_str))
247254

248-
// FIXME if the usual multi-line layout is too wide, we should fall back to
249-
// Foo {
250-
// a: ...,
251-
// }
255+
match context.config.struct_lit_style {
256+
StructLitStyle::BlockIndent if fields_str.contains('\n') => {
257+
let inner_indent = make_indent(context.block_indent + context.config.tab_spaces);
258+
let outer_indent = make_indent(context.block_indent);
259+
Some(format!("{} {{\n{}{}\n{}}}", path_str, inner_indent, fields_str, outer_indent))
260+
}
261+
_ => Some(format!("{} {{ {} }}", path_str, fields_str)),
262+
}
263+
264+
// FIXME if context.config.struct_lit_style == VisualIndent, but we run out
265+
// of space, we should fall back to BlockIndent.
252266
}
253267

254268
fn rewrite_field(context: &RewriteContext,

src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,19 @@ pub enum ReturnIndent {
111111

112112
impl_enum_decodable!(ReturnIndent, WithArgs, WithWhereClause);
113113

114+
// How to stle a struct literal.
115+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
116+
pub enum StructLitStyle {
117+
// First line on the same line as the opening brace, all lines aligned with
118+
// the first line.
119+
VisualIndent,
120+
// First line is on a new line and all lines align with block indent.
121+
BlockIndent,
122+
// FIXME Maybe we should also have an option to align types.
123+
}
124+
125+
impl_enum_decodable!(StructLitStyle, VisualIndent, BlockIndent);
126+
114127
enum ErrorKind {
115128
// Line has exceeded character limit
116129
LineOverflow,

tests/config/reorder_imports.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ fn_return_indent = "WithArgs"
88
fn_args_paren_newline = true
99
struct_trailing_comma = "Vertical"
1010
struct_lit_trailing_comma = "Vertical"
11+
struct_lit_style = "BlockIndent"
1112
enum_trailing_comma = true
1213
report_todo = "Always"
1314
report_fixme = "Never"

tests/config/small_tabs.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ fn_return_indent = "WithArgs"
88
fn_args_paren_newline = true
99
struct_trailing_comma = "Vertical"
1010
struct_lit_trailing_comma = "Vertical"
11+
struct_lit_style = "BlockIndent"
1112
enum_trailing_comma = true
1213
report_todo = "Always"
1314
report_fixme = "Never"

tests/config/visual_struct_lits.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
max_width = 100
2+
ideal_width = 80
3+
leeway = 5
4+
tab_spaces = 4
5+
newline_style = "Unix"
6+
fn_brace_style = "SameLineWhere"
7+
fn_return_indent = "WithArgs"
8+
fn_args_paren_newline = true
9+
struct_trailing_comma = "Vertical"
10+
struct_lit_style = "VisualIndent"
11+
struct_lit_trailing_comma = "Vertical"
12+
enum_trailing_comma = true
13+
report_todo = "Always"
14+
report_fixme = "Never"
15+
reorder_imports = false

tests/source/struct_lits_visual.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// rustfmt-config: visual_struct_lits.toml
2+
3+
// Struct literal expressions.
4+
5+
fn main() {
6+
let x = Bar;
7+
8+
// Comment
9+
let y = Foo {a: x };
10+
11+
Foo { a: foo() /* comment*/, /* comment*/ b: bar(), ..something };
12+
13+
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(), b: bar(), };
14+
15+
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
16+
// Comment
17+
a: foo(), // Comment
18+
// Comment
19+
b: bar(), // Comment
20+
};
21+
22+
Foo { a:Bar,
23+
b:foo() };
24+
25+
A {
26+
// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor.
27+
first: item(),
28+
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
29+
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
30+
second: Item
31+
};
32+
33+
Diagram { /* o This graph demonstrates how
34+
* / \ significant whitespace is
35+
* o o preserved.
36+
* /|\ \
37+
* o o o o */
38+
graph: G, }
39+
}

tests/target/struct_lits.rs

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,35 @@ fn main() {
66
// Comment
77
let y = Foo { a: x };
88

9-
Foo { a: foo(), // comment
10-
// comment
11-
b: bar(),
12-
..something };
13-
14-
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(),
15-
b: bar(), };
9+
Foo {
10+
a: foo(), // comment
11+
// comment
12+
b: bar(),
13+
..something
14+
};
15+
16+
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
17+
a: foo(),
18+
b: bar(),
19+
};
1620

1721
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { // Comment
18-
a: foo(), /* C
19-
* o
20-
* m
21-
* m
22-
* e
23-
* n
24-
* t */
25-
// Comment
26-
b: bar(), /* C
27-
* o
28-
* m
29-
* m
30-
* e
31-
* n
32-
* t */ };
22+
a: foo(), /* C
23+
* o
24+
* m
25+
* m
26+
* e
27+
* n
28+
* t */
29+
// Comment
30+
b: bar(), /* C
31+
* o
32+
* m
33+
* m
34+
* e
35+
* n
36+
* t */
37+
};
3338

3439
Foo { a: Bar, b: foo() };
3540

@@ -39,12 +44,14 @@ fn main() {
3944
first: item(),
4045
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
4146
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
42-
second: Item, };
47+
second: Item,
48+
};
4349

4450
Diagram { // o This graph demonstrates how
4551
// / \ significant whitespace is
4652
// o o preserved.
4753
// /|\ \
4854
// o o o o
49-
graph: G, }
55+
graph: G,
56+
}
5057
}

tests/target/struct_lits_visual.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// rustfmt-config: visual_struct_lits.toml
2+
3+
// Struct literal expressions.
4+
5+
fn main() {
6+
let x = Bar;
7+
8+
// Comment
9+
let y = Foo { a: x };
10+
11+
Foo { a: foo(), // comment
12+
// comment
13+
b: bar(),
14+
..something };
15+
16+
Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { a: foo(),
17+
b: bar(), };
18+
19+
Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo { // Comment
20+
a: foo(), /* C
21+
* o
22+
* m
23+
* m
24+
* e
25+
* n
26+
* t */
27+
// Comment
28+
b: bar(), /* C
29+
* o
30+
* m
31+
* m
32+
* e
33+
* n
34+
* t */ };
35+
36+
Foo { a: Bar, b: foo() };
37+
38+
A { // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit
39+
// amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante
40+
// hendrerit. Donec et mollis dolor.
41+
first: item(),
42+
// Praesent et diam eget libero egestas mattis sit amet vitae augue.
43+
// Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
44+
second: Item, };
45+
46+
Diagram { // o This graph demonstrates how
47+
// / \ significant whitespace is
48+
// o o preserved.
49+
// /|\ \
50+
// o o o o
51+
graph: G, }
52+
}

0 commit comments

Comments
 (0)