refactor rewrite_match and impl rewrite_result for ArmWrapper
This commit is contained in:
parent
babc2f9b8a
commit
ea02de27ff
@ -183,7 +183,7 @@ pub(crate) fn format_expr(
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Match(ref cond, ref arms, kind) => {
|
||||
rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs, kind)
|
||||
rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs, kind).ok()
|
||||
}
|
||||
ast::ExprKind::Path(ref qself, ref path) => {
|
||||
rewrite_path(context, PathContext::Expr, qself, path, shape).ok()
|
||||
|
104
src/matches.rs
104
src/matches.rs
@ -13,7 +13,7 @@
|
||||
ExprType, RhsTactics,
|
||||
};
|
||||
use crate::lists::{itemize_list, write_list, ListFormatting};
|
||||
use crate::rewrite::{Rewrite, RewriteContext};
|
||||
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
|
||||
use crate::shape::Shape;
|
||||
use crate::source_map::SpanUtils;
|
||||
use crate::spanned::Spanned;
|
||||
@ -55,6 +55,10 @@ fn span(&self) -> Span {
|
||||
|
||||
impl<'a> Rewrite for ArmWrapper<'a> {
|
||||
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||
self.rewrite_result(context, shape).ok()
|
||||
}
|
||||
|
||||
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
|
||||
rewrite_match_arm(
|
||||
context,
|
||||
self.arm,
|
||||
@ -73,7 +77,7 @@ pub(crate) fn rewrite_match(
|
||||
span: Span,
|
||||
attrs: &[ast::Attribute],
|
||||
match_kind: MatchKind,
|
||||
) -> Option<String> {
|
||||
) -> RewriteResult {
|
||||
// Do not take the rhs overhead from the upper expressions into account
|
||||
// when rewriting match condition.
|
||||
let cond_shape = Shape {
|
||||
@ -82,10 +86,14 @@ pub(crate) fn rewrite_match(
|
||||
};
|
||||
// 6 = `match `
|
||||
let cond_shape = match context.config.indent_style() {
|
||||
IndentStyle::Visual => cond_shape.shrink_left(6)?,
|
||||
IndentStyle::Block => cond_shape.offset_left(6)?,
|
||||
IndentStyle::Visual => cond_shape
|
||||
.shrink_left(6)
|
||||
.max_width_error(shape.width, span)?,
|
||||
IndentStyle::Block => cond_shape
|
||||
.offset_left(6)
|
||||
.max_width_error(shape.width, span)?,
|
||||
};
|
||||
let cond_str = cond.rewrite(context, cond_shape)?;
|
||||
let cond_str = cond.rewrite_result(context, cond_shape)?;
|
||||
let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
|
||||
let block_sep = match context.config.control_brace_style() {
|
||||
ControlBraceStyle::AlwaysNextLine => alt_block_sep,
|
||||
@ -109,7 +117,7 @@ pub(crate) fn rewrite_match(
|
||||
_ => shape.block_indent(context.config.tab_spaces()),
|
||||
};
|
||||
inner_attrs
|
||||
.rewrite(context, shape)
|
||||
.rewrite_result(context, shape)
|
||||
.map(|s| format!("{}{}\n", nested_indent_str, s))?
|
||||
};
|
||||
|
||||
@ -129,16 +137,16 @@ pub(crate) fn rewrite_match(
|
||||
if arms.is_empty() {
|
||||
let snippet = context.snippet(mk_sp(open_brace_pos, span.hi() - BytePos(1)));
|
||||
if snippet.trim().is_empty() {
|
||||
Some(format!("match {cond_str} {{}}"))
|
||||
Ok(format!("match {cond_str} {{}}"))
|
||||
} else {
|
||||
// Empty match with comments or inner attributes? We are not going to bother, sorry ;)
|
||||
Some(context.snippet(span).to_owned())
|
||||
Ok(context.snippet(span).to_owned())
|
||||
}
|
||||
} else {
|
||||
let span_after_cond = mk_sp(cond.span.hi(), span.hi());
|
||||
|
||||
match match_kind {
|
||||
MatchKind::Prefix => Some(format!(
|
||||
MatchKind::Prefix => Ok(format!(
|
||||
"match {}{}{{\n{}{}{}\n{}}}",
|
||||
cond_str,
|
||||
block_sep,
|
||||
@ -147,7 +155,7 @@ pub(crate) fn rewrite_match(
|
||||
rewrite_match_arms(context, arms, shape, span_after_cond, open_brace_pos)?,
|
||||
shape.indent.to_string(context.config),
|
||||
)),
|
||||
MatchKind::Postfix => Some(format!(
|
||||
MatchKind::Postfix => Ok(format!(
|
||||
"{}.match{}{{\n{}{}{}\n{}}}",
|
||||
cond_str,
|
||||
block_sep,
|
||||
@ -197,7 +205,7 @@ fn rewrite_match_arms(
|
||||
shape: Shape,
|
||||
span: Span,
|
||||
open_brace_pos: BytePos,
|
||||
) -> Option<String> {
|
||||
) -> RewriteResult {
|
||||
let arm_shape = shape
|
||||
.block_indent(context.config.tab_spaces())
|
||||
.with_max_width(context.config);
|
||||
@ -228,7 +236,7 @@ fn rewrite_match_arms(
|
||||
.separator("")
|
||||
.preserve_newline(true);
|
||||
|
||||
write_list(&arms_vec, &fmt)
|
||||
write_list(&arms_vec, &fmt).unknown_error()
|
||||
}
|
||||
|
||||
fn rewrite_match_arm(
|
||||
@ -237,19 +245,19 @@ fn rewrite_match_arm(
|
||||
shape: Shape,
|
||||
is_last: bool,
|
||||
has_leading_pipe: bool,
|
||||
) -> Option<String> {
|
||||
) -> RewriteResult {
|
||||
let (missing_span, attrs_str) = if !arm.attrs.is_empty() {
|
||||
if contains_skip(&arm.attrs) {
|
||||
let (_, body) = flatten_arm_body(context, arm.body.as_deref()?, None);
|
||||
let (_, body) = flatten_arm_body(context, arm.body.as_deref().unknown_error()?, None);
|
||||
// `arm.span()` does not include trailing comma, add it manually.
|
||||
return Some(format!(
|
||||
return Ok(format!(
|
||||
"{}{}",
|
||||
context.snippet(arm.span()),
|
||||
arm_comma(context.config, body, is_last),
|
||||
));
|
||||
}
|
||||
let missing_span = mk_sp(arm.attrs[arm.attrs.len() - 1].span.hi(), arm.pat.span.lo());
|
||||
(missing_span, arm.attrs.rewrite(context, shape)?)
|
||||
(missing_span, arm.attrs.rewrite_result(context, shape)?)
|
||||
} else {
|
||||
(mk_sp(arm.span().lo(), arm.span().lo()), String::new())
|
||||
};
|
||||
@ -263,19 +271,25 @@ fn rewrite_match_arm(
|
||||
};
|
||||
|
||||
// Patterns
|
||||
let pat_shape = match &arm.body.as_ref()?.kind {
|
||||
let pat_shape = match &arm.body.as_ref().unknown_error()?.kind {
|
||||
ast::ExprKind::Block(_, Some(label)) => {
|
||||
// Some block with a label ` => 'label: {`
|
||||
// 7 = ` => : {`
|
||||
let label_len = label.ident.as_str().len();
|
||||
shape.sub_width(7 + label_len)?.offset_left(pipe_offset)?
|
||||
shape
|
||||
.sub_width(7 + label_len)
|
||||
.and_then(|s| s.offset_left(pipe_offset))
|
||||
.max_width_error(shape.width, arm.span)?
|
||||
}
|
||||
_ => {
|
||||
// 5 = ` => {`
|
||||
shape.sub_width(5)?.offset_left(pipe_offset)?
|
||||
shape
|
||||
.sub_width(5)
|
||||
.and_then(|s| s.offset_left(pipe_offset))
|
||||
.max_width_error(shape.width, arm.span)?
|
||||
}
|
||||
};
|
||||
let pats_str = arm.pat.rewrite(context, pat_shape)?;
|
||||
let pats_str = arm.pat.rewrite_result(context, pat_shape)?;
|
||||
|
||||
// Guard
|
||||
let block_like_pat = trimmed_last_line_width(&pats_str) <= context.config.tab_spaces();
|
||||
@ -295,12 +309,16 @@ fn rewrite_match_arm(
|
||||
missing_span,
|
||||
shape,
|
||||
false,
|
||||
)?;
|
||||
)
|
||||
.unknown_error()?;
|
||||
|
||||
let arrow_span = mk_sp(arm.pat.span.hi(), arm.body.as_ref()?.span().lo());
|
||||
let arrow_span = mk_sp(
|
||||
arm.pat.span.hi(),
|
||||
arm.body.as_ref().unknown_error()?.span().lo(),
|
||||
);
|
||||
rewrite_match_body(
|
||||
context,
|
||||
arm.body.as_ref()?,
|
||||
arm.body.as_ref().unknown_error()?,
|
||||
&lhs_str,
|
||||
shape,
|
||||
guard_str.contains('\n'),
|
||||
@ -381,7 +399,7 @@ fn rewrite_match_body(
|
||||
has_guard: bool,
|
||||
arrow_span: Span,
|
||||
is_last: bool,
|
||||
) -> Option<String> {
|
||||
) -> RewriteResult {
|
||||
let (extend, body) = flatten_arm_body(
|
||||
context,
|
||||
body,
|
||||
@ -402,7 +420,7 @@ fn rewrite_match_body(
|
||||
_ => " ",
|
||||
};
|
||||
|
||||
Some(format!("{} =>{}{}{}", pats_str, block_sep, body_str, comma))
|
||||
Ok(format!("{} =>{}{}{}", pats_str, block_sep, body_str, comma))
|
||||
};
|
||||
|
||||
let next_line_indent = if !is_block || is_empty_block {
|
||||
@ -429,7 +447,7 @@ fn rewrite_match_body(
|
||||
if comment_str.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
rewrite_comment(comment_str, false, shape, context.config)?
|
||||
rewrite_comment(comment_str, false, shape, context.config).unknown_error()?
|
||||
}
|
||||
};
|
||||
|
||||
@ -446,7 +464,7 @@ fn rewrite_match_body(
|
||||
result.push_str(&nested_indent_str);
|
||||
result.push_str(body_str);
|
||||
result.push_str(comma);
|
||||
return Some(result);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
let indent_str = shape.indent.to_string_with_newline(context.config);
|
||||
@ -489,7 +507,7 @@ fn rewrite_match_body(
|
||||
result.push_str(&block_sep);
|
||||
result.push_str(body_str);
|
||||
result.push_str(&body_suffix);
|
||||
Some(result)
|
||||
Ok(result)
|
||||
};
|
||||
|
||||
// Let's try and get the arm body on the same line as the condition.
|
||||
@ -539,7 +557,7 @@ fn rewrite_match_body(
|
||||
combine_next_line_body(next_line_str)
|
||||
}
|
||||
(None, Some(ref next_line_str)) => combine_next_line_body(next_line_str),
|
||||
(None, None) => None,
|
||||
(None, None) => Err(RewriteError::Unknown),
|
||||
(Some(ref orig_str), _) => combine_orig_body(orig_str),
|
||||
}
|
||||
}
|
||||
@ -553,7 +571,7 @@ fn rewrite_guard(
|
||||
// the arm (excludes offset).
|
||||
pattern_width: usize,
|
||||
multiline_pattern: bool,
|
||||
) -> Option<String> {
|
||||
) -> RewriteResult {
|
||||
if let Some(ref guard) = *guard {
|
||||
// First try to fit the guard string on the same line as the pattern.
|
||||
// 4 = ` if `, 5 = ` => {`
|
||||
@ -562,9 +580,9 @@ fn rewrite_guard(
|
||||
.and_then(|s| s.sub_width(5));
|
||||
if !multiline_pattern {
|
||||
if let Some(cond_shape) = cond_shape {
|
||||
if let Some(cond_str) = guard.rewrite(context, cond_shape) {
|
||||
if let Ok(cond_str) = guard.rewrite_result(context, cond_shape) {
|
||||
if !cond_str.contains('\n') || pattern_width <= context.config.tab_spaces() {
|
||||
return Some(format!(" if {cond_str}"));
|
||||
return Ok(format!(" if {cond_str}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -574,20 +592,16 @@ fn rewrite_guard(
|
||||
// 3 = `if `, 5 = ` => {`
|
||||
let cond_shape = Shape::indented(shape.indent.block_indent(context.config), context.config)
|
||||
.offset_left(3)
|
||||
.and_then(|s| s.sub_width(5));
|
||||
if let Some(cond_shape) = cond_shape {
|
||||
if let Some(cond_str) = guard.rewrite(context, cond_shape) {
|
||||
return Some(format!(
|
||||
"{}if {}",
|
||||
cond_shape.indent.to_string_with_newline(context.config),
|
||||
cond_str
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
.and_then(|s| s.sub_width(5))
|
||||
.max_width_error(shape.width, guard.span)?;
|
||||
let cond_str = guard.rewrite_result(context, cond_shape)?;
|
||||
Ok(format!(
|
||||
"{}if {}",
|
||||
cond_shape.indent.to_string_with_newline(context.config),
|
||||
cond_str
|
||||
))
|
||||
} else {
|
||||
Some(String::new())
|
||||
Ok(String::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user