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(
39 ctx: &AssistContext<'_>,
41 let qm_kw = ctx.find_token_syntax_at_offset(T![?])?;
42 let qm_kw_parent = qm_kw.parent().and_then(ast::TryExpr::cast)?;
44 let expr = qm_kw_parent.expr()?;
45 let expr_type_info = ctx.sema.type_of_expr(&expr)?;
47 let try_enum = TryEnum::from_ty(&ctx.sema, &expr_type_info.original)?;
49 let target = qm_kw_parent.syntax().text_range();
51 AssistId("replace_try_expr_with_match", AssistKind::RefactorRewrite),
52 "Replace try expression with match",
55 let sad_pat = match try_enum {
56 TryEnum::Option => make::path_pat(make::ext::ident_path("None")),
57 TryEnum::Result => make::tuple_struct_pat(
58 make::ext::ident_path("Err"),
59 iter::once(make::path_pat(make::ext::ident_path("err"))),
63 let sad_expr = match try_enum {
65 make::expr_return(Some(make::expr_path(make::ext::ident_path("None"))))
67 TryEnum::Result => make::expr_return(Some(make::expr_call(
68 make::expr_path(make::ext::ident_path("Err")),
69 make::arg_list(iter::once(make::expr_path(make::ext::ident_path("err")))),
73 let happy_arm = make::match_arm(
75 try_enum.happy_pattern(make::ident_pat(false, false, make::name("it")).into()),
78 make::expr_path(make::ext::ident_path("it")),
80 let sad_arm = make::match_arm(iter::once(sad_pat), None, sad_expr);
82 let match_arm_list = make::match_arm_list([happy_arm, sad_arm]);
84 let expr_match = make::expr_match(expr, match_arm_list)
85 .indent(IndentLevel::from_node(qm_kw_parent.syntax()));
86 edit.replace_ast::<ast::Expr>(qm_kw_parent.into(), expr_match);
95 use crate::tests::{check_assist, check_assist_not_applicable};
98 fn test_replace_try_expr_with_match_not_applicable() {
99 check_assist_not_applicable(
100 replace_try_expr_with_match,
110 fn test_replace_try_expr_with_match_option() {
112 replace_try_expr_with_match,
116 let pat = Some(true)$0?;
121 let pat = match Some(true) {
131 fn test_replace_try_expr_with_match_result() {
133 replace_try_expr_with_match,
137 let pat = Ok(true)$0?;
142 let pat = match Ok(true) {
144 Err(err) => return Err(err),