ide_assists/handlers/
flip_or_pattern.rs1use syntax::{
2 Direction, T,
3 algo::non_trivia_sibling,
4 ast::{self, AstNode},
5};
6
7use crate::{AssistContext, AssistId, Assists};
8
9pub(crate) fn flip_or_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
25 let pipe = ctx.find_token_syntax_at_offset(T![|])?;
27
28 let parent = ast::OrPat::cast(pipe.parent()?)?;
29
30 let before = non_trivia_sibling(pipe.clone().into(), Direction::Prev)?.into_node()?;
31 let after = non_trivia_sibling(pipe.clone().into(), Direction::Next)?.into_node()?;
32
33 let target = pipe.text_range();
34 acc.add(AssistId::refactor_rewrite("flip_or_pattern"), "Flip patterns", target, |builder| {
35 let mut editor = builder.make_editor(parent.syntax());
36 editor.replace(before.clone(), after.clone());
37 editor.replace(after, before);
38 builder.add_file_edits(ctx.vfs_file_id(), editor);
39 })
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
47
48 #[test]
49 fn flip_or_pattern_assist_available() {
50 check_assist_target(flip_or_pattern, "fn main(a |$0 b: ()) {}", "|")
51 }
52
53 #[test]
54 fn flip_or_pattern_not_applicable_for_leading_pipe() {
55 check_assist_not_applicable(flip_or_pattern, "fn main(|$0 b: ()) {}")
56 }
57
58 #[test]
59 fn flip_or_pattern_works() {
60 check_assist(
61 flip_or_pattern,
62 "fn foo() { let (a | b |$0 c | d) = 1; }",
63 "fn foo() { let (a | c | b | d) = 1; }",
64 )
65 }
66
67 #[test]
68 fn flip_or_pattern_works_match_guard() {
69 check_assist(
70 flip_or_pattern,
71 "fn foo() { match() { a |$0 b if true => () }}",
72 "fn foo() { match() { b | a if true => () }}",
73 )
74 }
75}