Skip to content

Commit d58732c

Browse files
refactor: support tuple lit chain parent indent
1 parent 0a8b110 commit d58732c

7 files changed

+259
-23
lines changed

Configurations.md

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -428,52 +428,114 @@ fn example() {
428428
Determines whether block-like chain parents are indented
429429

430430
- **Default value**: `"Never"`
431-
- **Possible values**: `"Always"`, `"Never"`, `"OnlySimpleCalls"`
431+
- **Possible values**: `"Always"`, `"Never"`, `"OnlySimpleCalls"`, `"OnlyTupleLitsAndSimpleCalls"`
432432
- **Stable**: No (tracking issue: ...)
433433

434434
#### `"Never"` (default):
435+
The body of block-like parent chain elements are never indented.
435436

436437
```rust
437438
#![rustfmt::skip]
438-
439439
fn example() {
440+
let all = very_very_very_very_very_long_fun_name(
441+
very_very_very_very_very_very_very_very_very_long_var_name,
442+
)
443+
.iter()
444+
.map(|x| x + very_very_very_very_very_very_long_var_name);
445+
440446
StructA {
441447
test_test: some_value,
442448
}
443-
.foo()
444-
.bar()
445-
.baz()
446-
.qux();
447-
448-
let very_very_very_very_very_very_very_very_very_long_var_name = 13;
449-
let all = very_very_very_very_very_long_fun_name(
450-
very_very_very_very_very_very_very_very_very_long_var_name,
449+
.do_stuff(StructB {
450+
test_test_b: other_value,
451+
})
452+
.aaa_aaa()
453+
.do_stuff(
454+
StructB {
455+
test_test_b: other_value,
456+
}
457+
.ddd_ddd()
458+
.eee_eee(),
451459
)
452-
.iter()
453-
.map(|x| x + very_very_very_very_very_very_long_var_name);
460+
.bbb_bbb()
461+
.ccc_ccc();
454462

455463
foo(|x| {
456464
// ....
457465
})
458-
.bar()
459-
.baz()
460-
.unwrap();
466+
.bar()
467+
.baz()
468+
.unwrap();
461469
}
462470
```
463471

464472
#### `"Always"`:
473+
The body of block-like parent chain elements are always indented.
465474

466475
```rust
467476
#![rustfmt::skip]
477+
// chains_block_parent_indent_children: true
468478

469479
fn example() {
480+
let all = very_very_very_very_very_long_fun_name(
481+
very_very_very_very_very_very_very_very_very_long_var_name,
482+
)
483+
.iter()
484+
.map(|x| x + very_very_very_very_very_very_long_var_name);
485+
470486
StructA {
471487
test_test: some_value,
472488
}
473-
.foo()
489+
.do_stuff(StructB {
490+
test_test_b: other_value,
491+
})
492+
.aaa_aaa()
493+
.do_stuff(
494+
StructB {
495+
test_test_b: other_value,
496+
}
497+
.ddd_ddd()
498+
.eee_eee(),
499+
)
500+
.bbb_bbb()
501+
.ccc_ccc();
502+
503+
foo(|x| {
504+
// ....
505+
})
474506
.bar()
475507
.baz()
476-
.qux();
508+
.unwrap()
509+
}
510+
```
511+
512+
#### `"OnlyTupleLitsAndSimpleCalls"`:
513+
514+
```rust
515+
#![rustfmt::skip]
516+
517+
fn example() {
518+
let all = very_very_very_very_very_long_fun_name(
519+
very_very_very_very_very_very_very_very_very_long_var_name,
520+
)
521+
.iter()
522+
.map(|x| x + very_very_very_very_very_very_long_var_name);
523+
StructA {
524+
test_test: some_value,
525+
}
526+
.do_stuff(StructB {
527+
test_test_b: other_value,
528+
})
529+
.aaa_aaa()
530+
.do_stuff(
531+
StructB {
532+
test_test_b: other_value,
533+
}
534+
.ddd_ddd()
535+
.eee_eee(),
536+
)
537+
.bbb_bbb()
538+
.ccc_ccc();
477539
}
478540
```
479541

src/chains.rs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,17 @@ fn format_chain_item(
765765
}
766766
}
767767

768+
fn is_tup_lit_or_simple_call_like(
769+
parent_expr_kind: &ast::ExprKind,
770+
context: &RewriteContext<'_>,
771+
shape: Shape,
772+
) -> bool {
773+
match parent_expr_kind {
774+
ast::ExprKind::Struct(..) => true,
775+
_ => is_simple_call_like(parent_expr_kind, context, shape),
776+
}
777+
}
778+
768779
let orig_result = item.rewrite(context, shape);
769780
let new_shape = match Shape::indented(shape.indent.block_indent(context.config), context.config)
770781
.sub_width(shape.rhs_overhead(context.config))
@@ -783,12 +794,38 @@ fn format_chain_item(
783794
}
784795
(Some(orig_result), Some(next_line_result)) => match item.kind {
785796
ChainItemKind::Parent(ref expr) => match parent_indent_style {
786-
ChainsBlockParentElementIndent::Never => Some((orig_result, false)),
787-
ChainsBlockParentElementIndent::Always => Some((next_line_result, false)),
797+
ChainsBlockParentElementIndent::Never => Some((
798+
orig_result.clone(),
799+
wrap_str(orig_result, context.config.max_width(), shape).is_none(),
800+
)),
801+
ChainsBlockParentElementIndent::Always => Some((
802+
next_line_result.clone(),
803+
wrap_str(next_line_result, context.config.max_width(), new_shape).is_none(),
804+
)),
788805
ChainsBlockParentElementIndent::OnlySimpleCalls => {
789806
match is_simple_call_like(&expr.kind, &context, shape) {
790-
true => Some((next_line_result, false)),
791-
false => Some((orig_result, false)),
807+
true => Some((
808+
next_line_result.clone(),
809+
wrap_str(next_line_result, context.config.max_width(), new_shape)
810+
.is_none(),
811+
)),
812+
false => Some((
813+
orig_result.clone(),
814+
wrap_str(orig_result, context.config.max_width(), shape).is_none(),
815+
)),
816+
}
817+
}
818+
ChainsBlockParentElementIndent::OnlyTupleLitsAndSimpleCalls => {
819+
match is_tup_lit_or_simple_call_like(&expr.kind, &context, shape) {
820+
true => Some((
821+
next_line_result.clone(),
822+
wrap_str(next_line_result, context.config.max_width(), new_shape)
823+
.is_none(),
824+
)),
825+
false => Some((
826+
orig_result.clone(),
827+
wrap_str(orig_result, context.config.max_width(), shape).is_none(),
828+
)),
792829
}
793830
}
794831
},
@@ -798,7 +835,10 @@ fn format_chain_item(
798835
)),
799836
},
800837
(None, None) => Some((context.snippet(item.span).to_owned(), true)),
801-
(Some(orig_result), _) => Some((orig_result, false)),
838+
(Some(orig_result), _) => Some((
839+
orig_result.clone(),
840+
wrap_str(orig_result, context.config.max_width(), shape).is_none(),
841+
)),
802842
// This will only occur when the chain is part of the rhs and
803843
// will fit with an indent on the next line
804844
(None, Some(_)) => None,

src/config/options.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,13 @@ pub enum ChainsBlockParentElementIndent {
178178
/// Always indent the contents of a block-like parent element.
179179
Always,
180180
/// Only indent the contents of a block-like parent element if
181-
/// it is call-like, such as a function call that does not include
181+
/// it is a simple call-like, such as a function call that does not include
182182
/// any block-like arguments.
183183
OnlySimpleCalls,
184+
/// Only indent the contents of a block-like parent element if
185+
/// it is a tuple lit or a simple call-like, such as a function call that does not include
186+
/// any block-like arguments.
187+
OnlyTupleLitsAndSimpleCalls,
184188
}
185189

186190
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]

tests/source/chains_long_items_block.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,25 @@ fn long_tail() {
5454
bar().xxxxxxx.map(|x| x + 5).map(|x| x / 2).fold(0, |acc, x| acc + x).doooooooooooooooooooooooooooooooooooooooooooooooooooooo_stufffffffffffffffffffffffffffffffffffffff();
5555

5656
let foo = bar().xxxxxxx.map(|x| x + 5).map(|x| x / 2).fold(0, |acc, x| acc + x).doooooooooooooooooooooooooooooooooooooooooooooooooooooo_stufffffffffffffffffffffffffffffffffffffff();
57+
}
5758

59+
fn raw_str_lit() {
60+
fpo.foo().bar.baz.quz.adfasdfasdfasdfasdfasdfasdfasffffffffffffffffffffffffffffffffffdfasf(r#"
61+
if foo {
62+
a();
63+
}
64+
else {
65+
b();
66+
}
67+
"#.trim());
68+
69+
70+
fpo.foo().bar.baz.quz.a999999999999999999999999999999999999999999999999999999999999999(r#"
71+
if foo {
72+
a();
73+
}
74+
else {
75+
b();
76+
}
77+
"#.trim().foo().bar.baz.qux().unwrap());
5878
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// rustfmt-chains_block_parent_indent_children: true
2+
// rustfmt-chains_block_parent_indent_parent_item: OnlyTupleLitsAndSimpleCalls
3+
4+
fn main() {
5+
let very_very_very_very_very_very_very_very_very_long_var_name = 13;
6+
let all = very_very_very_very_very_long_fun_name(
7+
very_very_very_very_very_very_very_very_very_long_var_name,
8+
)
9+
.iter()
10+
.map(|x| x + very_very_very_very_very_very_long_var_name);
11+
StructA {
12+
test_test: some_value,
13+
}
14+
.do_stuff(StructB {
15+
test_test_b: other_value,
16+
})
17+
.aaa_aaa()
18+
.do_stuff(StructB {
19+
test_test_b: other_value,
20+
}.ddd_ddd().eee_eee())
21+
.bbb_bbb()
22+
.ccc_ccc();
23+
let more = 13;
24+
let other = vec![1, 2, 3].iter()
25+
.map(|x| x + very_very_very_very_very_very_long_var_name);
26+
27+
foo(|x| {
28+
// ....
29+
})
30+
.bar()
31+
.baz()
32+
.unwrap()
33+
}

tests/target/chains_long_items_block.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,42 @@ fn long_tail() {
143143
.doooooooooooooooooooooooooooooooooooooooooooooooooooooo_stufffffffffffffffffffffffffffffffffffffff(
144144
);
145145
}
146+
147+
fn raw_str_lit() {
148+
fpo.foo()
149+
.bar
150+
.baz
151+
.quz
152+
.adfasdfasdfasdfasdfasdfasdfasffffffffffffffffffffffffffffffffffdfasf(
153+
r#"
154+
if foo {
155+
a();
156+
}
157+
else {
158+
b();
159+
}
160+
"#
161+
.trim(),
162+
);
163+
164+
fpo.foo()
165+
.bar
166+
.baz
167+
.quz
168+
.a999999999999999999999999999999999999999999999999999999999999999(
169+
r#"
170+
if foo {
171+
a();
172+
}
173+
else {
174+
b();
175+
}
176+
"#
177+
.trim()
178+
.foo()
179+
.bar
180+
.baz
181+
.qux()
182+
.unwrap(),
183+
);
184+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// rustfmt-chains_block_parent_indent_children: true
2+
// rustfmt-chains_block_parent_indent_parent_item: OnlyTupleLitsAndSimpleCalls
3+
4+
fn main() {
5+
let very_very_very_very_very_very_very_very_very_long_var_name = 13;
6+
let all = very_very_very_very_very_long_fun_name(
7+
very_very_very_very_very_very_very_very_very_long_var_name,
8+
)
9+
.iter()
10+
.map(|x| x + very_very_very_very_very_very_long_var_name);
11+
StructA {
12+
test_test: some_value,
13+
}
14+
.do_stuff(StructB {
15+
test_test_b: other_value,
16+
})
17+
.aaa_aaa()
18+
.do_stuff(
19+
StructB {
20+
test_test_b: other_value,
21+
}
22+
.ddd_ddd()
23+
.eee_eee(),
24+
)
25+
.bbb_bbb()
26+
.ccc_ccc();
27+
let more = 13;
28+
let other = vec![1, 2, 3]
29+
.iter()
30+
.map(|x| x + very_very_very_very_very_very_long_var_name);
31+
32+
foo(|x| {
33+
// ....
34+
})
35+
.bar()
36+
.baz()
37+
.unwrap()
38+
}

0 commit comments

Comments
 (0)