From 2fda8dd883f5de6989280884a37e408981dfc2ee Mon Sep 17 00:00:00 2001 From: Marcus Klaas Date: Sun, 19 Jul 2015 22:25:44 +0200 Subject: [PATCH] Format if-let-else expressions --- src/expr.rs | 61 +++++++++++++++++++++++++++++++++++--------- tests/source/expr.rs | 14 ++++++++++ tests/target/expr.rs | 17 ++++++++++++ 3 files changed, 80 insertions(+), 12 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 89846527cfff..68b780b414af 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -84,6 +84,16 @@ impl Rewrite for ast::Expr { cond, if_block, else_block.as_ref().map(|e| &**e), + None, + width, + offset) + } + ast::Expr_::ExprIfLet(ref pat, ref cond, ref if_block, ref else_block) => { + rewrite_if_else(context, + cond, + if_block, + else_block.as_ref().map(|e| &**e), + Some(pat), width, offset) } @@ -112,9 +122,16 @@ impl Rewrite for ast::Block { } } +// TODO(#18): implement pattern formatting +impl Rewrite for ast::Pat { + fn rewrite(&self, context: &RewriteContext, _: usize, _: usize) -> Option { + context.codemap.span_to_snippet(self.span).ok() + } +} + fn rewrite_label(label: Option) -> String { match label { - Some(ident) => format!("{}: ", ident.as_str()), + Some(ident) => format!("{}: ", ident), None => "".to_owned() } } @@ -123,23 +140,43 @@ fn rewrite_if_else(context: &RewriteContext, cond: &ast::Expr, if_block: &ast::Block, else_block: Option<&ast::Expr>, + pat: Option<&ast::Pat>, width: usize, offset: usize) -> Option { // FIXME: missing comments between control statements and blocks - let cond_string = try_opt!(cond.rewrite(context, width - 3 - 2, offset + 3)); - let if_block_string = try_opt!(if_block.rewrite(context, width, offset)); + // 3 = "if ", 2 = " {" + let pat_string = match pat { + Some(pat) => { + // 7 = "let ".len() + " = ".len() + // 4 = "let ".len() + let pat_string = try_opt!(pat.rewrite(context, width - 3 - 2 - 7, offset + 3 + 4)); + format!("let {} = ", pat_string) + } + None => String::new() + }; - match else_block { - Some(else_block) => { - else_block.rewrite(context, width, offset).map(|else_block_string| { - format!("if {} {} else {}", cond_string, if_block_string, else_block_string) - }) - } - None => { - Some(format!("if {} {}", cond_string, if_block_string)) - } + // Consider only the last line of the pat string + let extra_offset = match pat_string.rfind('\n') { + // 1 for newline character + Some(idx) => pat_string.len() - idx - 1 - offset, + None => 3 + pat_string.len() + }; + + let cond_string = try_opt!(cond.rewrite(context, + width - extra_offset - 2, + offset + extra_offset)); + let if_block_string = try_opt!(if_block.rewrite(context, width, offset)); + let mut result = format!("if {}{} {}", pat_string, cond_string, if_block_string); + + if let Some(else_block) = else_block { + let else_block_string = try_opt!(else_block.rewrite(context, width, offset)); + + result.push_str(" else "); + result.push_str(&else_block_string); } + + Some(result) } fn rewrite_string_lit(context: &RewriteContext, diff --git a/tests/source/expr.rs b/tests/source/expr.rs index d26c57ebbd00..19baa90ace26 100644 --- a/tests/source/expr.rs +++ b/tests/source/expr.rs @@ -16,6 +16,20 @@ some_ridiculously_loooooooooooooooooooooong_function(10000 * 30000000000 + 40000 if 1 + 2 > 0 { let result = 5; result } else { 4}; + if let Some(x) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { + // Nothing + } + + if let Some(x) = (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {} + + if let (some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1 + + 2 + 3 { + } + + if let (some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1111 + 2222 {} + if cond() { something(); } else if different_cond() { diff --git a/tests/target/expr.rs b/tests/target/expr.rs index 3a8605b7c429..86ad2dd406d7 100644 --- a/tests/target/expr.rs +++ b/tests/target/expr.rs @@ -22,6 +22,23 @@ fn foo() -> bool { 4 }; + if let Some(x) = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { + // Nothing + } + + if let Some(x) = (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) { + } + + if let (some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1 + 2 + 3 { + } + + if let (some_very_large, + tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuple) = 1111 + + 2222 { + } + if cond() { something(); } else if different_cond() {