Skip to content

Commit e168a45

Browse files
committed
clarified logic for formatting the type bounds as a list
1 parent 255f9b4 commit e168a45

File tree

2 files changed

+47
-31
lines changed

2 files changed

+47
-31
lines changed

src/lists.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,19 @@ pub(crate) struct ListFormatting<'a> {
2222
trailing_separator: SeparatorTactic,
2323
separator_place: SeparatorPlace,
2424
shape: Shape,
25-
// Non-expressions, e.g., items, will have a new line at the end of the list.
26-
// Important for comment styles.
25+
/// Non-expressions, e.g., items, will have a new line at the end of the list.
26+
/// Important for comment styles.
2727
ends_with_newline: bool,
28-
// Remove newlines between list elements for expressions.
28+
/// Remove newlines between list elements for expressions.
2929
preserve_newline: bool,
30-
// Nested import lists get some special handling for the "Mixed" list type
30+
/// Nested import lists get some special handling for the "Mixed" list type.
3131
nested: bool,
32-
// Whether comments should be visually aligned.
32+
/// Whether comments should be visually aligned.
3333
align_comments: bool,
3434
config: &'a Config,
35-
item_on_newline: Vec<bool>,
35+
/// The decision of putting an item on a newline is determined by the caller.
36+
custom_list_tactic: Vec<bool>,
37+
/// Whether whitespaces should be added around the separator.
3638
padding: bool,
3739
}
3840

@@ -49,7 +51,7 @@ impl<'a> ListFormatting<'a> {
4951
nested: false,
5052
align_comments: true,
5153
config,
52-
item_on_newline: Vec::new(),
54+
custom_list_tactic: Vec::new(),
5355
padding: true,
5456
}
5557
}
@@ -59,8 +61,8 @@ impl<'a> ListFormatting<'a> {
5961
self
6062
}
6163

62-
pub(crate) fn item_on_newline(mut self, item_on_newline: Vec<bool>) -> Self {
63-
self.item_on_newline = item_on_newline;
64+
pub(crate) fn custom_list_tactic(mut self, custom_list_tactic: Vec<bool>) -> Self {
65+
self.custom_list_tactic = custom_list_tactic;
6466
self
6567
}
6668

@@ -325,6 +327,19 @@ where
325327
}
326328

327329
match tactic {
330+
_ if !formatting.custom_list_tactic.is_empty() => {
331+
if *formatting
332+
.custom_list_tactic
333+
.get(i)
334+
.expect("invalid custom_list_tactic formatting option")
335+
{
336+
result.push('\n');
337+
result.push_str(indent_str);
338+
first_item_on_line = true;
339+
} else if formatting.padding && !first_item_on_line {
340+
result.push(' ');
341+
}
342+
}
328343
DefinitiveListTactic::Horizontal if !first && formatting.padding => {
329344
result.push(' ');
330345
}
@@ -351,13 +366,10 @@ where
351366
let total_width = total_item_width(item) + item_sep_len;
352367

353368
// 1 is space between separator and item.
354-
if (!formatting.item_on_newline.is_empty() && formatting.item_on_newline[i])
355-
|| formatting.item_on_newline.is_empty()
356-
&& ((line_len > 0 && line_len + 1 + total_width > formatting.shape.width)
357-
|| prev_item_had_post_comment
358-
|| (formatting.nested
359-
&& (prev_item_is_nested_import
360-
|| (!first && inner_item.contains("::")))))
369+
if (line_len > 0 && line_len + 1 + total_width > formatting.shape.width)
370+
|| prev_item_had_post_comment
371+
|| (formatting.nested
372+
&& (prev_item_is_nested_import || (!first && inner_item.contains("::"))))
361373
{
362374
result.push('\n');
363375
result.push_str(indent_str);
@@ -950,7 +962,7 @@ pub(crate) fn struct_lit_formatting<'a>(
950962
nested: false,
951963
align_comments: true,
952964
config: context.config,
953-
item_on_newline: Vec::new(),
965+
custom_list_tactic: Vec::new(),
954966
padding: true,
955967
}
956968
}

src/types.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -855,23 +855,27 @@ fn join_bounds(
855855
ast::GenericBound::Trait(..) => last_line_extendable(s),
856856
};
857857
let generic_bounds_in_order = is_generic_bounds_in_order(items);
858-
let mut item_on_newline = if generic_bounds_in_order {
859-
items
860-
.iter()
861-
.zip(type_strs.iter())
862-
.map(|(bound, bound_str)| !is_bound_extendable(bound_str.inner_as_ref(), bound))
863-
.collect::<Vec<bool>>()
864-
} else {
865-
vec![true; items.len()]
866-
};
867-
item_on_newline.insert(0, false);
868858
let fmt = ListFormatting::new(shape, context.config)
869859
.padding(false)
870-
.item_on_newline(item_on_newline)
871-
.trailing_separator(SeparatorTactic::Always)
872-
.separator_place(SeparatorPlace::Front)
873860
.separator(joiner)
874-
.tactic(DefinitiveListTactic::Mixed);
861+
.trailing_separator(SeparatorTactic::Always)
862+
.separator_place(SeparatorPlace::Front);
863+
let fmt = if generic_bounds_in_order {
864+
let custom_list_tactic = std::iter::once(false) // no newline before the first bound
865+
.chain(
866+
items
867+
.iter()
868+
.zip(type_strs.iter())
869+
.map(|(bound, bound_str)| {
870+
// putting a newline before the current bound depends on the previous bound
871+
!is_bound_extendable(bound_str.inner_as_ref(), bound)
872+
}),
873+
)
874+
.collect::<Vec<bool>>();
875+
fmt.custom_list_tactic(custom_list_tactic)
876+
} else {
877+
fmt.tactic(DefinitiveListTactic::Vertical)
878+
};
875879
write_list(&type_strs, &fmt)
876880
}
877881

0 commit comments

Comments
 (0)