diff --git a/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs b/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs new file mode 100644 index 0000000000000..b897ddc24578e --- /dev/null +++ b/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs @@ -0,0 +1,124 @@ +use syntax::ast::{self, AstNode}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: replace_is_some_with_if_let_some +// +// Replace `if x.is_some()` with `if let Some(_tmp) = x` or `if x.is_ok()` with `if let Ok(_tmp) = x`. +// +// ``` +// fn main() { +// let x = Some(1); +// if x.is_som$0e() {} +// } +// ``` +// -> +// ``` +// fn main() { +// let x = Some(1); +// if let Some(_tmp) = x {} +// } +// ``` +pub(crate) fn replace_is_method_with_if_let_method( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { + let if_expr = ctx.find_node_at_offset::()?; + + let cond = if_expr.condition()?; + let call_expr = match cond { + ast::Expr::MethodCallExpr(call) => call, + _ => return None, + }; + + let name_ref = call_expr.name_ref()?; + match name_ref.text().as_str() { + "is_some" | "is_ok" => { + let receiver = call_expr.receiver()?; + let target = call_expr.syntax().text_range(); + + let (assist_id, message, text) = if name_ref.text() == "is_some" { + ("replace_is_some_with_if_let_some", "Replace `is_some` with `if let Some`", "Some") + } else { + ("replace_is_ok_with_if_let_ok", "Replace `is_ok` with `if let Ok`", "Ok") + }; + + acc.add(AssistId(assist_id, AssistKind::RefactorRewrite), message, target, |edit| { + let replacement = format!("let {}(_tmp) = {}", text, receiver); + edit.replace(target, replacement); + }) + } + _ => return None, + } +} + +#[cfg(test)] +mod tests { + use crate::tests::{check_assist, check_assist_not_applicable}; + + use super::replace_is_method_with_if_let_method; + + #[test] + fn replace_is_some_with_if_let_some_works() { + check_assist( + replace_is_method_with_if_let_method, + r#" +fn main() { + let x = Some(1); + if x.is_som$0e() {} +} +"#, + r#" +fn main() { + let x = Some(1); + if let Some(_tmp) = x {} +} +"#, + ); + } + + #[test] + fn replace_is_some_with_if_let_some_not_applicable() { + check_assist_not_applicable( + replace_is_method_with_if_let_method, + r#" +fn main() { + let x = Some(1); + if x.is_non$0e() {} +} +"#, + ); + } + + #[test] + fn replace_is_ok_with_if_let_ok_works() { + check_assist( + replace_is_method_with_if_let_method, + r#" +fn main() { + let x = Ok(1); + if x.is_o$0k() {} +} +"#, + r#" +fn main() { + let x = Ok(1); + if let Ok(_tmp) = x {} +} +"#, + ); + } + + #[test] + fn replace_is_ok_with_if_let_ok_not_applicable() { + check_assist_not_applicable( + replace_is_method_with_if_let_method, + r#" +fn main() { + let x = Ok(1); + if x.is_e$0rr() {} +} +"#, + ); + } +} diff --git a/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs b/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs deleted file mode 100644 index 70892fe27025d..0000000000000 --- a/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs +++ /dev/null @@ -1,90 +0,0 @@ -use syntax::ast::{self, AstNode}; - -use crate::{AssistContext, AssistId, AssistKind, Assists}; - -// Assist: replace_is_some_with_if_let_some -// -// Replace `if x.is_some()` with `if let Some(_tmp) = x`. -// -// ``` -// fn main() { -// let x = Some(1); -// if x.is_som$0e() {} -// } -// ``` -// -> -// ``` -// fn main() { -// let x = Some(1); -// if let Some(_tmp) = x {} -// } -// ``` -pub(crate) fn replace_is_some_with_if_let_some( - acc: &mut Assists, - ctx: &AssistContext<'_>, -) -> Option<()> { - let if_expr = ctx.find_node_at_offset::()?; - - let cond = if_expr.condition()?; - let call_expr = match cond { - ast::Expr::MethodCallExpr(call) => call, - _ => return None, - }; - - let name_ref = call_expr.name_ref()?; - if name_ref.text() != "is_some" { - return None; - } - - let receiver = call_expr.receiver()?; - let target = call_expr.syntax().text_range(); - - acc.add( - AssistId("replace_is_some_with_if_let_some", AssistKind::RefactorRewrite), - "Replace `is_some` with `if let Some`", - target, - |edit| { - let replacement = format!("let Some(_tmp) = {}", receiver); - edit.replace(target, replacement); - }, - ) -} - -#[cfg(test)] -mod tests { - use crate::tests::{check_assist, check_assist_not_applicable}; - - use super::replace_is_some_with_if_let_some; - - #[test] - fn replace_is_some_with_if_let_some_works() { - check_assist( - replace_is_some_with_if_let_some, - r#" -fn main() { - let x = Some(1); - if x.is_som$0e() {} -} -"#, - r#" -fn main() { - let x = Some(1); - if let Some(_tmp) = x {} -} -"#, - ); - } - - #[test] - fn replace_is_some_with_if_let_some_not_applicable() { - check_assist_not_applicable( - replace_is_some_with_if_let_some, - r#" -fn main() { - let x = Some(1); - if x.is_non$0e() {} -} -"#, - ); - } -} diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs index d6accbb097eec..d2b291631c8ad 100644 --- a/crates/ide-assists/src/lib.rs +++ b/crates/ide-assists/src/lib.rs @@ -195,6 +195,7 @@ mod handlers { mod replace_try_expr_with_match; mod replace_derive_with_manual_impl; mod replace_if_let_with_match; + mod replace_is_method_with_if_let_method; mod replace_method_eager_lazy; mod replace_arith_op; mod introduce_named_generic; @@ -213,7 +214,6 @@ mod handlers { mod unwrap_block; mod unwrap_result_return_type; mod unqualify_method_call; - mod replace_is_some_with_if_let_some; mod wrap_return_type_in_result; mod into_to_qualified_from; @@ -314,6 +314,7 @@ mod handlers { replace_derive_with_manual_impl::replace_derive_with_manual_impl, replace_if_let_with_match::replace_if_let_with_match, replace_if_let_with_match::replace_match_with_if_let, + replace_is_method_with_if_let_method::replace_is_method_with_if_let_method, replace_let_with_if_let::replace_let_with_if_let, replace_method_eager_lazy::replace_with_eager_method, replace_method_eager_lazy::replace_with_lazy_method, @@ -333,7 +334,6 @@ mod handlers { unwrap_result_return_type::unwrap_result_return_type, unwrap_tuple::unwrap_tuple, unqualify_method_call::unqualify_method_call, - replace_is_some_with_if_let_some::replace_is_some_with_if_let_some, wrap_return_type_in_result::wrap_return_type_in_result, // These are manually sorted for better priorities. By default, // priority is determined by the size of the target range (smaller