diff --git a/src/attr.rs b/src/attr.rs index 555c0eb96e7c..2ec47d305728 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -14,7 +14,7 @@ use comment::{contains_comment, rewrite_doc_comment}; use config::lists::*; use config::IndentStyle; use expr::rewrite_literal; -use lists::{itemize_list, write_list, ListFormatting}; +use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator}; use rewrite::{Rewrite, RewriteContext}; use shape::Shape; use types::{rewrite_path, PathContext}; @@ -294,19 +294,10 @@ where ListTactic::HorizontalVertical }; - let tactic = - ::lists::definitive_tactic(&item_vec, tactic, ::lists::Separator::Comma, shape.width); - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: SeparatorTactic::Never, - separator_place: SeparatorPlace::Back, - shape, - ends_with_newline: false, - preserve_newline: false, - nested: false, - config: context.config, - }; + let tactic = definitive_tactic(&item_vec, tactic, Separator::Comma, shape.width); + let fmt = ListFormatting::new(shape, context.config) + .tactic(tactic) + .ends_with_newline(false); let item_str = write_list(&item_vec, &fmt)?; let one_line_budget = one_line_shape.width; diff --git a/src/closures.rs b/src/closures.rs index c03c8e6b6065..1a4a6e44fdfb 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -270,17 +270,9 @@ fn rewrite_closure_fn_decl( _ => arg_shape, }; - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: SeparatorTactic::Never, - separator_place: SeparatorPlace::Back, - shape: arg_shape, - ends_with_newline: false, - preserve_newline: true, - nested: false, - config: context.config, - }; + let fmt = ListFormatting::new(arg_shape, context.config) + .tactic(tactic) + .preserve_newline(true); let list_str = write_list(&item_vec, &fmt)?; let mut prefix = format!("{}{}{}|{}|", is_async, immovable, mover, list_str); diff --git a/src/expr.rs b/src/expr.rs index 72cf618dca54..0f4474d7c0f1 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1197,17 +1197,11 @@ pub fn rewrite_multiple_patterns( shape.width, ) }; - let fmt = ListFormatting { - tactic, - separator: " |", - trailing_separator: SeparatorTactic::Never, - separator_place: context.config.binop_separator(), - shape, - ends_with_newline: false, - preserve_newline: false, - nested: false, - config: context.config, - }; + let fmt = ListFormatting::new(shape, context.config) + .tactic(tactic) + .separator(" |") + .separator_place(context.config.binop_separator()) + .ends_with_newline(false); write_list(&items, &fmt) } @@ -1760,17 +1754,9 @@ where Separator::Comma, nested_shape.width, ); - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: SeparatorTactic::Never, - separator_place: SeparatorPlace::Back, - shape, - ends_with_newline: false, - preserve_newline: false, - nested: false, - config: context.config, - }; + let fmt = ListFormatting::new(shape, context.config) + .tactic(tactic) + .ends_with_newline(false); let list_str = write_list(&item_vec, &fmt)?; Some(format!("({})", list_str)) diff --git a/src/imports.rs b/src/imports.rs index cfb4ecc648b4..2007d05bc548 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -714,21 +714,17 @@ fn rewrite_nested_use_tree( let ends_with_newline = context.config.imports_indent() == IndentStyle::Block && tactic != DefinitiveListTactic::Horizontal; - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: if ends_with_newline { - context.config.trailing_comma() - } else { - SeparatorTactic::Never - }, - separator_place: SeparatorPlace::Back, - shape: nested_shape, - ends_with_newline, - preserve_newline: true, - nested: has_nested_list, - config: context.config, + let trailing_separator = if ends_with_newline { + context.config.trailing_comma() + } else { + SeparatorTactic::Never }; + let fmt = ListFormatting::new(nested_shape, context.config) + .tactic(tactic) + .trailing_separator(trailing_separator) + .ends_with_newline(ends_with_newline) + .preserve_newline(true) + .nested(has_nested_list); let list_str = write_list(&list_items, &fmt)?; diff --git a/src/items.rs b/src/items.rs index b352294d3f3c..0152fb8794c3 100644 --- a/src/items.rs +++ b/src/items.rs @@ -529,17 +529,9 @@ impl<'a> FmtVisitor<'a> { } let shape = self.shape().sub_width(2)?; - let fmt = ListFormatting { - tactic: DefinitiveListTactic::Vertical, - separator: ",", - trailing_separator: self.config.trailing_comma(), - separator_place: SeparatorPlace::Back, - shape, - ends_with_newline: true, - preserve_newline: true, - nested: false, - config: self.config, - }; + let fmt = ListFormatting::new(shape, self.config) + .trailing_separator(self.config.trailing_comma()) + .preserve_newline(true); let list = write_list(&items, &fmt)?; result.push_str(&list); @@ -2360,22 +2352,16 @@ fn rewrite_args( debug!("rewrite_args: budget: {}, tactic: {:?}", budget, tactic); - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: if variadic { - SeparatorTactic::Never - } else { - trailing_comma - }, - separator_place: SeparatorPlace::Back, - shape: Shape::legacy(budget, indent), - ends_with_newline: tactic.ends_with_newline(context.config.indent_style()), - preserve_newline: true, - nested: false, - config: context.config, + let trailing_separator = if variadic { + SeparatorTactic::Never + } else { + trailing_comma }; - + let fmt = ListFormatting::new(Shape::legacy(budget, indent), context.config) + .tactic(tactic) + .trailing_separator(trailing_separator) + .ends_with_newline(tactic.ends_with_newline(context.config.indent_style())) + .preserve_newline(true); write_list(&arg_items, &fmt) } @@ -2551,17 +2537,10 @@ fn rewrite_where_clause_rfc_style( DefinitiveListTactic::Vertical }; - let fmt = ListFormatting { - tactic: shape_tactic, - separator: ",", - trailing_separator: comma_tactic, - separator_place: SeparatorPlace::Back, - shape: clause_shape, - ends_with_newline: true, - preserve_newline: true, - nested: false, - config: context.config, - }; + let fmt = ListFormatting::new(clause_shape, context.config) + .tactic(shape_tactic) + .trailing_separator(comma_tactic) + .preserve_newline(true); let preds_str = write_list(&items.collect::>(), &fmt)?; let comment_separator = |comment: &str, shape: Shape| { @@ -2666,17 +2645,11 @@ fn rewrite_where_clause( comma_tactic = SeparatorTactic::Never; } - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: comma_tactic, - separator_place: SeparatorPlace::Back, - shape: Shape::legacy(budget, offset), - ends_with_newline: tactic.ends_with_newline(context.config.indent_style()), - preserve_newline: true, - nested: false, - config: context.config, - }; + let fmt = ListFormatting::new(Shape::legacy(budget, offset), context.config) + .tactic(tactic) + .trailing_separator(comma_tactic) + .ends_with_newline(tactic.ends_with_newline(context.config.indent_style())) + .preserve_newline(true); let preds_str = write_list(&item_vec, &fmt)?; let end_length = if terminator == "{" { diff --git a/src/lists.rs b/src/lists.rs index 0e3baa7c1e15..f7a6f9944cd9 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -24,22 +24,71 @@ use utils::{count_newlines, first_line_width, last_line_width, mk_sp, starts_wit use visitor::SnippetProvider; pub struct ListFormatting<'a> { - pub tactic: DefinitiveListTactic, - pub separator: &'a str, - pub trailing_separator: SeparatorTactic, - pub separator_place: SeparatorPlace, - pub shape: Shape, + tactic: DefinitiveListTactic, + separator: &'a str, + trailing_separator: SeparatorTactic, + separator_place: SeparatorPlace, + shape: Shape, // Non-expressions, e.g. items, will have a new line at the end of the list. // Important for comment styles. - pub ends_with_newline: bool, + ends_with_newline: bool, // Remove newlines between list elements for expressions. - pub preserve_newline: bool, + preserve_newline: bool, // Nested import lists get some special handling for the "Mixed" list type - pub nested: bool, - pub config: &'a Config, + nested: bool, + config: &'a Config, } impl<'a> ListFormatting<'a> { + pub fn new(shape: Shape, config: &'a Config) -> Self { + ListFormatting { + tactic: DefinitiveListTactic::Vertical, + separator: ",", + trailing_separator: SeparatorTactic::Never, + separator_place: SeparatorPlace::Back, + shape, + ends_with_newline: true, + preserve_newline: false, + nested: false, + config: config, + } + } + + pub fn tactic(mut self, tactic: DefinitiveListTactic) -> Self { + self.tactic = tactic; + self + } + + pub fn separator(mut self, separator: &'a str) -> Self { + self.separator = separator; + self + } + + pub fn trailing_separator(mut self, trailing_separator: SeparatorTactic) -> Self { + self.trailing_separator = trailing_separator; + self + } + + pub fn separator_place(mut self, separator_place: SeparatorPlace) -> Self { + self.separator_place = separator_place; + self + } + + pub fn ends_with_newline(mut self, ends_with_newline: bool) -> Self { + self.ends_with_newline = ends_with_newline; + self + } + + pub fn preserve_newline(mut self, preserve_newline: bool) -> Self { + self.preserve_newline = preserve_newline; + self + } + + pub fn nested(mut self, nested: bool) -> Self { + self.nested = nested; + self + } + pub fn needs_trailing_separator(&self) -> bool { match self.trailing_separator { // We always put separator in front. diff --git a/src/macros.rs b/src/macros.rs index f00bb339cb09..b32de753fdad 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -412,17 +412,10 @@ pub fn rewrite_macro_def( false, ).collect::>(); - let fmt = ListFormatting { - tactic: DefinitiveListTactic::Vertical, - separator: if def.legacy { ";" } else { "" }, - trailing_separator: SeparatorTactic::Always, - separator_place: SeparatorPlace::Back, - shape: arm_shape, - ends_with_newline: true, - preserve_newline: true, - nested: false, - config: context.config, - }; + let fmt = ListFormatting::new(arm_shape, context.config) + .separator(if def.legacy { ";" } else { "" }) + .trailing_separator(SeparatorTactic::Always) + .preserve_newline(true); if multi_branch_style { result += " {"; diff --git a/src/matches.rs b/src/matches.rs index 791f34cefe8d..29e9f19ad7dc 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -215,18 +215,10 @@ fn rewrite_match_arms( false, ); let arms_vec: Vec<_> = items.collect(); - let fmt = ListFormatting { - tactic: DefinitiveListTactic::Vertical, - // We will add/remove commas inside `arm.rewrite()`, and hence no separator here. - separator: "", - trailing_separator: SeparatorTactic::Never, - separator_place: SeparatorPlace::Back, - shape: arm_shape, - ends_with_newline: true, - preserve_newline: true, - nested: false, - config: context.config, - }; + // We will add/remove commas inside `arm.rewrite()`, and hence no separator here. + let fmt = ListFormatting::new(arm_shape, context.config) + .separator("") + .preserve_newline(true); write_list(&arms_vec, &fmt) } diff --git a/src/overflow.rs b/src/overflow.rs index 54e594d814f8..e18fe140c8de 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -363,32 +363,27 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> { // indentation. If its first line fits on one line with the other arguments, // we format the function arguments horizontally. let tactic = self.try_overflow_last_item(&mut list_items); - - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: if let Some(tactic) = self.force_separator_tactic { - tactic - } else if !self.context.use_block_indent() { - SeparatorTactic::Never - } else if tactic == DefinitiveListTactic::Mixed { - // We are using mixed layout because everything did not fit within a single line. - SeparatorTactic::Always - } else { - self.context.config.trailing_comma() - }, - separator_place: SeparatorPlace::Back, - shape: self.nested_shape, - ends_with_newline: match tactic { - DefinitiveListTactic::Vertical | DefinitiveListTactic::Mixed => { - self.context.use_block_indent() - } - _ => false, - }, - preserve_newline: false, - nested: false, - config: self.context.config, + let trailing_separator = if let Some(tactic) = self.force_separator_tactic { + tactic + } else if !self.context.use_block_indent() { + SeparatorTactic::Never + } else if tactic == DefinitiveListTactic::Mixed { + // We are using mixed layout because everything did not fit within a single line. + SeparatorTactic::Always + } else { + self.context.config.trailing_comma() }; + let ends_with_newline = match tactic { + DefinitiveListTactic::Vertical | DefinitiveListTactic::Mixed => { + self.context.use_block_indent() + } + _ => false, + }; + + let fmt = ListFormatting::new(self.nested_shape, self.context.config) + .tactic(tactic) + .trailing_separator(trailing_separator) + .ends_with_newline(ends_with_newline); write_list(&list_items, &fmt) .map(|items_str| (tactic == DefinitiveListTactic::Horizontal, items_str)) diff --git a/src/patterns.rs b/src/patterns.rs index dbe0c8a6f662..7ab43def8c77 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -214,7 +214,7 @@ fn rewrite_struct_pat( if ellipsis { if fields_str.contains('\n') || fields_str.len() > one_line_width { // Add a missing trailing comma. - if fmt.trailing_separator == SeparatorTactic::Never { + if context.config.trailing_comma() == SeparatorTactic::Never { fields_str.push_str(","); } fields_str.push_str("\n"); @@ -223,7 +223,7 @@ fn rewrite_struct_pat( } else { if !fields_str.is_empty() { // there are preceding struct fields being matched on - if fmt.tactic == DefinitiveListTactic::Vertical { + if tactic == DefinitiveListTactic::Vertical { // if the tactic is Vertical, write_list already added a trailing , fields_str.push_str(" "); } else { diff --git a/src/reorder.rs b/src/reorder.rs index 48ddd1163379..bc429a10ab6a 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -16,7 +16,7 @@ // FIXME(#2455): Reorder trait items. -use config::{lists::*, Config}; +use config::Config; use syntax::{ast, attr, codemap::Span}; use attr::filter_inline_attrs; @@ -69,18 +69,7 @@ fn wrap_reorderable_items( list_items: &[ListItem], shape: Shape, ) -> Option { - let fmt = ListFormatting { - tactic: DefinitiveListTactic::Vertical, - separator: "", - trailing_separator: SeparatorTactic::Never, - separator_place: SeparatorPlace::Back, - shape, - ends_with_newline: true, - preserve_newline: false, - nested: false, - config: context.config, - }; - + let fmt = ListFormatting::new(shape, context.config).separator(""); write_list(list_items, &fmt) } diff --git a/src/types.rs b/src/types.rs index 5d57b99d32d8..360c7304988b 100644 --- a/src/types.rs +++ b/src/types.rs @@ -360,23 +360,17 @@ where Separator::Comma, budget, ); - - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: if !context.use_block_indent() || variadic { - SeparatorTactic::Never - } else { - context.config.trailing_comma() - }, - separator_place: SeparatorPlace::Back, - shape: list_shape, - ends_with_newline: tactic.ends_with_newline(context.config.indent_style()), - preserve_newline: true, - nested: false, - config: context.config, + let trailing_separator = if !context.use_block_indent() || variadic { + SeparatorTactic::Never + } else { + context.config.trailing_comma() }; + let fmt = ListFormatting::new(list_shape, context.config) + .tactic(tactic) + .trailing_separator(trailing_separator) + .ends_with_newline(tactic.ends_with_newline(context.config.indent_style())) + .preserve_newline(true); let list_str = write_list(&item_vec, &fmt)?; let ty_shape = match context.config.indent_style() { diff --git a/src/vertical.rs b/src/vertical.rs index ead5719f61f8..c6721bc5010e 100644 --- a/src/vertical.rs +++ b/src/vertical.rs @@ -245,17 +245,10 @@ fn rewrite_aligned_items_inner( one_line_width, ); - let fmt = ListFormatting { - tactic, - separator: ",", - trailing_separator: context.config.trailing_comma(), - separator_place: SeparatorPlace::Back, - shape: item_shape, - ends_with_newline: true, - preserve_newline: true, - nested: false, - config: context.config, - }; + let fmt = ListFormatting::new(item_shape, context.config) + .tactic(tactic) + .trailing_separator(context.config.trailing_comma()) + .preserve_newline(true); write_list(&items, &fmt) }