4 assists::{AssistId, AssistKind},
10 edit::{AstNodeEdit, IndentLevel},
16 use crate::assist_context::{AssistContext, Assists};
18 // Assist: replace_try_expr_with_match
20 // Replaces a `try` expression with a `match` expression.
23 // let pat = Some(true)$0?;
27 // let pat = match Some(true) {
29 // None => return None,
32 pub(crate) fn replace_try_expr_with_match(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
33 let qm_kw = ctx.find_token_syntax_at_offset(T![?])?;
34 let qm_kw_parent = qm_kw.parent().and_then(ast::TryExpr::cast)?;
36 let expr = qm_kw_parent.expr()?;
37 let expr_type_info = ctx.sema.type_of_expr(&expr)?;
39 let try_enum = TryEnum::from_ty(&ctx.sema, &expr_type_info.original)?;
41 let target = qm_kw_parent.syntax().text_range();
43 AssistId("replace_try_expr_with_match", AssistKind::RefactorRewrite),
44 "Replace try expression with match",
47 let sad_pat = match try_enum {
48 TryEnum::Option => make::path_pat(make::ext::ident_path("None")),
49 TryEnum::Result => make::tuple_struct_pat(
50 make::ext::ident_path("Err"),
51 iter::once(make::path_pat(make::ext::ident_path("err"))),
55 let sad_expr = match try_enum {
57 make::expr_return(Some(make::expr_path(make::ext::ident_path("None"))))
59 TryEnum::Result => make::expr_return(Some(make::expr_call(
60 make::expr_path(make::ext::ident_path("Err")),
61 make::arg_list(iter::once(make::expr_path(make::ext::ident_path("err")))),
65 let happy_arm = make::match_arm(
67 try_enum.happy_pattern(make::ident_pat(false, false, make::name("it")).into()),
70 make::expr_path(make::ext::ident_path("it")),
72 let sad_arm = make::match_arm(iter::once(sad_pat), None, sad_expr);
74 let match_arms = [happy_arm, sad_arm];
75 let match_arm_list = make::match_arm_list(std::array::IntoIter::new(match_arms));
77 let expr_match = make::expr_match(expr, match_arm_list)
78 .indent(IndentLevel::from_node(qm_kw_parent.syntax()));
79 edit.replace_ast::<ast::Expr>(qm_kw_parent.into(), expr_match);
88 use crate::tests::{check_assist, check_assist_not_applicable};
91 fn test_replace_try_expr_with_match_not_applicable() {
92 check_assist_not_applicable(
93 replace_try_expr_with_match,
103 fn test_replace_try_expr_with_match_option() {
105 replace_try_expr_with_match,
109 let pat = Some(true)$0?;
114 let pat = match Some(true) {
124 fn test_replace_try_expr_with_match_result() {
126 replace_try_expr_with_match,
130 let pat = Ok(true)$0?;
135 let pat = match Ok(true) {
137 Err(err) => return Err(err),