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 // # //- minicore:option
25 // let pat = Some(true)$0?;
31 // let pat = match Some(true) {
33 // None => return None,
37 pub(crate) fn replace_try_expr_with_match(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
38 let qm_kw = ctx.find_token_syntax_at_offset(T![?])?;
39 let qm_kw_parent = qm_kw.parent().and_then(ast::TryExpr::cast)?;
41 let expr = qm_kw_parent.expr()?;
42 let expr_type_info = ctx.sema.type_of_expr(&expr)?;
44 let try_enum = TryEnum::from_ty(&ctx.sema, &expr_type_info.original)?;
46 let target = qm_kw_parent.syntax().text_range();
48 AssistId("replace_try_expr_with_match", AssistKind::RefactorRewrite),
49 "Replace try expression with match",
52 let sad_pat = match try_enum {
53 TryEnum::Option => make::path_pat(make::ext::ident_path("None")),
54 TryEnum::Result => make::tuple_struct_pat(
55 make::ext::ident_path("Err"),
56 iter::once(make::path_pat(make::ext::ident_path("err"))),
60 let sad_expr = match try_enum {
62 make::expr_return(Some(make::expr_path(make::ext::ident_path("None"))))
64 TryEnum::Result => make::expr_return(Some(make::expr_call(
65 make::expr_path(make::ext::ident_path("Err")),
66 make::arg_list(iter::once(make::expr_path(make::ext::ident_path("err")))),
70 let happy_arm = make::match_arm(
72 try_enum.happy_pattern(make::ident_pat(false, false, make::name("it")).into()),
75 make::expr_path(make::ext::ident_path("it")),
77 let sad_arm = make::match_arm(iter::once(sad_pat), None, sad_expr);
79 let match_arm_list = make::match_arm_list([happy_arm, sad_arm]);
81 let expr_match = make::expr_match(expr, match_arm_list)
82 .indent(IndentLevel::from_node(qm_kw_parent.syntax()));
83 edit.replace_ast::<ast::Expr>(qm_kw_parent.into(), expr_match);
92 use crate::tests::{check_assist, check_assist_not_applicable};
95 fn test_replace_try_expr_with_match_not_applicable() {
96 check_assist_not_applicable(
97 replace_try_expr_with_match,
107 fn test_replace_try_expr_with_match_option() {
109 replace_try_expr_with_match,
113 let pat = Some(true)$0?;
118 let pat = match Some(true) {
128 fn test_replace_try_expr_with_match_result() {
130 replace_try_expr_with_match,
134 let pat = Ok(true)$0?;
139 let pat = match Ok(true) {
141 Err(err) => return Err(err),