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.rs80
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 => () }}",
+ )
+ }
+}