Refactor compute_budgets_for_args()
This commit is contained in:
parent
c67f729205
commit
ec6c2d6e99
104
src/items.rs
104
src/items.rs
@ -1835,21 +1835,15 @@ fn rewrite_fn_base(
|
||||
let ret_str_len = if multi_line_ret_str { 0 } else { ret_str.len() };
|
||||
|
||||
// Args.
|
||||
let (mut one_line_budget, mut multi_line_budget, mut arg_indent) =
|
||||
try_opt!(compute_budgets_for_args(
|
||||
context,
|
||||
&result,
|
||||
indent,
|
||||
ret_str_len,
|
||||
newline_brace,
|
||||
has_braces,
|
||||
));
|
||||
|
||||
if context.config.fn_args_layout() == IndentStyle::Block {
|
||||
arg_indent = indent.block_indent(context.config);
|
||||
// 1 = ","
|
||||
multi_line_budget = context.config.max_width() - (arg_indent.width() + 1);
|
||||
}
|
||||
let (one_line_budget, multi_line_budget, mut arg_indent) = try_opt!(compute_budgets_for_args(
|
||||
context,
|
||||
&result,
|
||||
indent,
|
||||
ret_str_len,
|
||||
newline_brace,
|
||||
has_braces,
|
||||
multi_line_ret_str,
|
||||
));
|
||||
|
||||
debug!(
|
||||
"rewrite_fn_base: one_line_budget: {}, multi_line_budget: {}, arg_indent: {:?}",
|
||||
@ -1885,10 +1879,6 @@ fn rewrite_fn_base(
|
||||
result.push(' ')
|
||||
}
|
||||
|
||||
if multi_line_ret_str {
|
||||
one_line_budget = 0;
|
||||
}
|
||||
|
||||
// A conservative estimation, to goal is to be over all parens in generics
|
||||
let args_start = generics
|
||||
.ty_params
|
||||
@ -1917,11 +1907,8 @@ fn rewrite_fn_base(
|
||||
generics_str.contains('\n'),
|
||||
));
|
||||
|
||||
let multi_line_arg_str =
|
||||
arg_str.contains('\n') || arg_str.chars().last().map_or(false, |c| c == ',');
|
||||
|
||||
let put_args_in_block = match context.config.fn_args_layout() {
|
||||
IndentStyle::Block => multi_line_arg_str || generics_str.contains('\n'),
|
||||
IndentStyle::Block => arg_str.contains('\n') || arg_str.len() > one_line_budget,
|
||||
_ => false,
|
||||
} && !fd.inputs.is_empty();
|
||||
|
||||
@ -1936,6 +1923,12 @@ fn rewrite_fn_base(
|
||||
result.push(')');
|
||||
} else {
|
||||
result.push_str(&arg_str);
|
||||
let used_width = last_line_used_width(&result, indent.width()) + first_line_width(&ret_str);
|
||||
// Put the closing brace on the next line if it overflows the max width.
|
||||
// 1 = `)`
|
||||
if fd.inputs.len() == 0 && used_width + 1 > context.config.max_width() {
|
||||
result.push('\n');
|
||||
}
|
||||
if context.config.spaces_within_parens() && fd.inputs.len() > 0 {
|
||||
result.push(' ')
|
||||
}
|
||||
@ -1954,15 +1947,16 @@ fn rewrite_fn_base(
|
||||
}
|
||||
|
||||
// Return type.
|
||||
if !ret_str.is_empty() {
|
||||
if let ast::FunctionRetTy::Ty(..) = fd.output {
|
||||
let ret_should_indent = match context.config.fn_args_layout() {
|
||||
// If our args are block layout then we surely must have space.
|
||||
IndentStyle::Block if put_args_in_block => false,
|
||||
IndentStyle::Block if put_args_in_block || fd.inputs.len() == 0 => false,
|
||||
_ if args_last_line_contains_comment => false,
|
||||
_ if result.contains('\n') || multi_line_ret_str => true,
|
||||
_ => {
|
||||
// If we've already gone multi-line, or the return type would push over the max
|
||||
// width, then put the return type on a new line. With the +1 for the signature
|
||||
// length an additional space between the closing parenthesis of the argument and
|
||||
// the arrow '->' is considered.
|
||||
// If the return type would push over the max width, then put the return type on
|
||||
// a new line. With the +1 for the signature length an additional space between
|
||||
// the closing parenthesis of the argument and the arrow '->' is considered.
|
||||
let mut sig_length = result.len() + indent.width() + ret_str_len + 1;
|
||||
|
||||
// If there is no where clause, take into account the space after the return type
|
||||
@ -1971,10 +1965,7 @@ fn rewrite_fn_base(
|
||||
sig_length += 2;
|
||||
}
|
||||
|
||||
let overlong_sig = sig_length > context.config.max_width();
|
||||
|
||||
(!args_last_line_contains_comment) &&
|
||||
(result.contains('\n') || multi_line_ret_str || overlong_sig)
|
||||
sig_length > context.config.max_width()
|
||||
}
|
||||
};
|
||||
let ret_indent = if ret_should_indent {
|
||||
@ -2276,6 +2267,7 @@ fn compute_budgets_for_args(
|
||||
ret_str_len: usize,
|
||||
newline_brace: bool,
|
||||
has_braces: bool,
|
||||
force_vertical_layout: bool,
|
||||
) -> Option<((usize, usize, Indent))> {
|
||||
debug!(
|
||||
"compute_budgets_for_args {} {:?}, {}, {}",
|
||||
@ -2285,7 +2277,7 @@ fn compute_budgets_for_args(
|
||||
newline_brace
|
||||
);
|
||||
// Try keeping everything on the same line.
|
||||
if !result.contains('\n') {
|
||||
if !result.contains('\n') && !force_vertical_layout {
|
||||
// 2 = `()`, 3 = `() `, space is before ret_string.
|
||||
let overhead = if ret_str_len == 0 { 2 } else { 3 };
|
||||
let mut used_space = indent.width() + result.len() + ret_str_len + overhead;
|
||||
@ -2306,31 +2298,45 @@ fn compute_budgets_for_args(
|
||||
|
||||
if one_line_budget > 0 {
|
||||
// 4 = "() {".len()
|
||||
let multi_line_overhead =
|
||||
indent.width() + result.len() + if newline_brace { 2 } else { 4 };
|
||||
let multi_line_budget =
|
||||
try_opt!(context.config.max_width().checked_sub(multi_line_overhead));
|
||||
let (indent, multi_line_budget) = match context.config.fn_args_layout() {
|
||||
IndentStyle::Block => {
|
||||
let indent = indent.block_indent(context.config);
|
||||
let budget =
|
||||
try_opt!(context.config.max_width().checked_sub(indent.width() + 1));
|
||||
(indent, budget)
|
||||
}
|
||||
IndentStyle::Visual => {
|
||||
let indent = indent + result.len() + 1;
|
||||
let multi_line_overhead =
|
||||
indent.width() + result.len() + if newline_brace { 2 } else { 4 };
|
||||
let budget =
|
||||
try_opt!(context.config.max_width().checked_sub(multi_line_overhead));
|
||||
(indent, budget)
|
||||
}
|
||||
};
|
||||
|
||||
return Some((
|
||||
one_line_budget,
|
||||
multi_line_budget,
|
||||
indent + result.len() + 1,
|
||||
));
|
||||
return Some((one_line_budget, multi_line_budget, indent));
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't work. we must force vertical layout and put args on a newline.
|
||||
let new_indent = indent.block_indent(context.config);
|
||||
// Account for `)` and possibly ` {`.
|
||||
let used_space = new_indent.width() + if ret_str_len == 0 { 1 } else { 3 };
|
||||
let used_space = match context.config.fn_args_layout() {
|
||||
// 1 = `,`
|
||||
IndentStyle::Block => new_indent.width() + 1,
|
||||
// Account for `)` and possibly ` {`.
|
||||
IndentStyle::Visual => new_indent.width() + if ret_str_len == 0 { 1 } else { 3 },
|
||||
};
|
||||
let max_space = try_opt!(context.config.max_width().checked_sub(used_space));
|
||||
Some((0, max_space, new_indent))
|
||||
}
|
||||
|
||||
fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause) -> bool {
|
||||
match config.fn_brace_style() {
|
||||
BraceStyle::AlwaysNextLine => true,
|
||||
BraceStyle::SameLineWhere if !where_clause.predicates.is_empty() => true,
|
||||
fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause, has_body: bool) -> bool {
|
||||
match (config.fn_brace_style(), config.where_density()) {
|
||||
(BraceStyle::AlwaysNextLine, _) => true,
|
||||
(_, Density::Compressed) if where_clause.predicates.len() == 1 => false,
|
||||
(_, Density::CompressedIfEmpty) if where_clause.predicates.len() == 1 && !has_body => false,
|
||||
(BraceStyle::SameLineWhere, _) if !where_clause.predicates.is_empty() => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user