Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/flip_or_pattern.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/flip_or_pattern.rs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/crates/ide-assists/src/handlers/flip_or_pattern.rs b/crates/ide-assists/src/handlers/flip_or_pattern.rs new file mode 100644 index 0000000000..d9fa03e719 --- /dev/null +++ b/crates/ide-assists/src/handlers/flip_or_pattern.rs @@ -0,0 +1,80 @@ +use syntax::{ + algo::non_trivia_sibling, + ast::{self, AstNode}, + Direction, T, +}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: flip_or_pattern +// +// Flips two patterns in an or-pattern. +// +// ``` +// fn foo() { +// let (a |$0 b) = 1; +// } +// ``` +// -> +// ``` +// fn foo() { +// let (b | a) = 1; +// } +// ``` +pub(crate) fn flip_or_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + // Only flip on the `|` token + let pipe = ctx.find_token_syntax_at_offset(T![|])?; + + let parent = ast::OrPat::cast(pipe.parent()?)?; + + let before = non_trivia_sibling(pipe.clone().into(), Direction::Prev)?.into_node()?; + let after = non_trivia_sibling(pipe.clone().into(), Direction::Next)?.into_node()?; + + let target = pipe.text_range(); + acc.add( + AssistId("flip_or_pattern", AssistKind::RefactorRewrite), + "Flip patterns", + target, + |builder| { + let mut editor = builder.make_editor(parent.syntax()); + editor.replace(before.clone(), after.clone()); + editor.replace(after, before); + builder.add_file_edits(ctx.file_id(), editor); + }, + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; + + #[test] + fn flip_or_pattern_assist_available() { + check_assist_target(flip_or_pattern, "fn main(a |$0 b: ()) {}", "|") + } + + #[test] + fn flip_or_pattern_not_applicable_for_leading_pipe() { + check_assist_not_applicable(flip_or_pattern, "fn main(|$0 b: ()) {}") + } + + #[test] + fn flip_or_pattern_works() { + check_assist( + flip_or_pattern, + "fn foo() { let (a | b |$0 c | d) = 1; }", + "fn foo() { let (a | c | b | d) = 1; }", + ) + } + + #[test] + fn flip_or_pattern_works_match_guard() { + check_assist( + flip_or_pattern, + "fn foo() { match() { a |$0 b if true => () }}", + "fn foo() { match() { b | a if true => () }}", + ) + } +} |