aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assists/replace_if_let_with_match.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-09-25 12:35:50 +0100
committerGitHub <[email protected]>2019-09-25 12:35:50 +0100
commit8f92309dbc00a0f88563030921706f205c01f452 (patch)
tree3e3f08ada8011f300faae3966cbe61a4a7dd7377 /crates/ra_assists/src/assists/replace_if_let_with_match.rs
parentd9b4835625ac96c7628e2ef66ef6e26cc48d231f (diff)
parent69689625ce4465f2d008d6543553d0d91d53dca4 (diff)
Merge #1909
1909: move ast builder to a separate file r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_assists/src/assists/replace_if_let_with_match.rs')
-rw-r--r--crates/ra_assists/src/assists/replace_if_let_with_match.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/crates/ra_assists/src/assists/replace_if_let_with_match.rs b/crates/ra_assists/src/assists/replace_if_let_with_match.rs
new file mode 100644
index 000000000..401835c57
--- /dev/null
+++ b/crates/ra_assists/src/assists/replace_if_let_with_match.rs
@@ -0,0 +1,102 @@
1use format_buf::format;
2use hir::db::HirDatabase;
3use ra_fmt::extract_trivial_expression;
4use ra_syntax::{ast, AstNode};
5
6use crate::{Assist, AssistCtx, AssistId};
7
8pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
9 let if_expr: ast::IfExpr = ctx.node_at_offset()?;
10 let cond = if_expr.condition()?;
11 let pat = cond.pat()?;
12 let expr = cond.expr()?;
13 let then_block = if_expr.then_branch()?;
14 let else_block = match if_expr.else_branch()? {
15 ast::ElseBranch::Block(it) => it,
16 ast::ElseBranch::IfExpr(_) => return None,
17 };
18
19 ctx.add_action(AssistId("replace_if_let_with_match"), "replace with match", |edit| {
20 let match_expr = build_match_expr(expr, pat, then_block, else_block);
21 edit.target(if_expr.syntax().text_range());
22 edit.replace_node_and_indent(if_expr.syntax(), match_expr);
23 edit.set_cursor(if_expr.syntax().text_range().start())
24 });
25
26 ctx.build()
27}
28
29fn build_match_expr(
30 expr: ast::Expr,
31 pat1: ast::Pat,
32 arm1: ast::BlockExpr,
33 arm2: ast::BlockExpr,
34) -> String {
35 let mut buf = String::new();
36 format!(buf, "match {} {{\n", expr.syntax().text());
37 format!(buf, " {} => {}\n", pat1.syntax().text(), format_arm(&arm1));
38 format!(buf, " _ => {}\n", format_arm(&arm2));
39 buf.push_str("}");
40 buf
41}
42
43fn format_arm(block: &ast::BlockExpr) -> String {
44 match extract_trivial_expression(block) {
45 None => block.syntax().text().to_string(),
46 Some(e) => format!("{},", e.syntax().text()),
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use crate::helpers::{check_assist, check_assist_target};
54
55 #[test]
56 fn test_replace_if_let_with_match_unwraps_simple_expressions() {
57 check_assist(
58 replace_if_let_with_match,
59 "
60impl VariantData {
61 pub fn is_struct(&self) -> bool {
62 if <|>let VariantData::Struct(..) = *self {
63 true
64 } else {
65 false
66 }
67 }
68} ",
69 "
70impl VariantData {
71 pub fn is_struct(&self) -> bool {
72 <|>match *self {
73 VariantData::Struct(..) => true,
74 _ => false,
75 }
76 }
77} ",
78 )
79 }
80
81 #[test]
82 fn replace_if_let_with_match_target() {
83 check_assist_target(
84 replace_if_let_with_match,
85 "
86impl VariantData {
87 pub fn is_struct(&self) -> bool {
88 if <|>let VariantData::Struct(..) = *self {
89 true
90 } else {
91 false
92 }
93 }
94} ",
95 "if let VariantData::Struct(..) = *self {
96 true
97 } else {
98 false
99 }",
100 );
101 }
102}