1use itertools::{Itertools, chain};
2use syntax::{
3 SyntaxKind::WHITESPACE,
4 TextRange,
5 ast::{
6 AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit,
7 prec::ExprPrecedence, syntax_factory::SyntaxFactory,
8 },
9 syntax_editor::Element,
10};
11
12use crate::{AssistContext, AssistId, Assists};
13
14pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
42 let match_arm = ctx.find_node_at_offset::<MatchArm>()?;
43 let guard = match_arm.guard()?;
44 if ctx.offset() > guard.syntax().text_range().end() {
45 cov_mark::hit!(move_guard_inapplicable_in_arm_body);
46 return None;
47 }
48 let rest_arms = rest_arms(&match_arm, ctx.selection_trimmed())?;
49 let space_before_delete = chain(
50 guard.syntax().prev_sibling_or_token(),
51 rest_arms.iter().filter_map(|it| it.syntax().prev_sibling_or_token()),
52 );
53 let space_after_arrow = match_arm.fat_arrow_token()?.next_sibling_or_token();
54
55 let arm_expr = match_arm.expr()?;
56 let make = SyntaxFactory::without_mappings();
57 let if_branch = chain([&match_arm], &rest_arms)
58 .rfold(None, |else_branch, arm| {
59 if let Some(guard) = arm.guard() {
60 let then_branch = crate::utils::wrap_block(&arm.expr()?, &make);
61 let guard_condition = guard.condition()?.reset_indent();
62 Some(make.expr_if(guard_condition, then_branch, else_branch).into())
63 } else {
64 arm.expr().map(|it| crate::utils::wrap_block(&it, &make).into())
65 }
66 })?
67 .indent(arm_expr.indent_level());
68 let ElseBranch::IfExpr(if_expr) = if_branch else { return None };
69
70 let target = guard.syntax().text_range();
71 acc.add(
72 AssistId::refactor_rewrite("move_guard_to_arm_body"),
73 "Move guard to arm body",
74 target,
75 |builder| {
76 let editor = builder.make_editor(match_arm.syntax());
77 for element in space_before_delete {
78 if element.kind() == WHITESPACE {
79 editor.delete(element);
80 }
81 }
82 for rest_arm in &rest_arms {
83 editor.delete(rest_arm.syntax());
84 }
85 if let Some(element) = space_after_arrow
86 && element.kind() == WHITESPACE
87 {
88 editor.replace(element, make.whitespace(" "));
89 }
90
91 editor.delete(guard.syntax());
92 editor.replace(arm_expr.syntax(), if_expr.syntax());
93 builder.add_file_edits(ctx.vfs_file_id(), editor);
94 },
95 )
96}
97
98pub(crate) fn move_arm_cond_to_match_guard(
124 acc: &mut Assists,
125 ctx: &AssistContext<'_, '_>,
126) -> Option<()> {
127 let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?;
128 let match_pat = match_arm.pat()?;
129 let arm_body = match_arm.expr()?;
130 let arm_guard = match_arm.guard().and_then(|it| it.condition());
131
132 let mut replace_node = None;
133 let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone()).or_else(|| {
134 let block_expr = BlockExpr::cast(arm_body.syntax().clone())?;
135 if block_expr.statements().next().is_some() {
136 cov_mark::hit!(move_guard_non_naked_if);
137 return None;
138 }
139 if let Expr::IfExpr(e) = block_expr.tail_expr()? {
140 replace_node = Some(block_expr.syntax().clone());
141 Some(e)
142 } else {
143 None
144 }
145 })?;
146 if ctx.offset() > if_expr.then_branch()?.syntax().text_range().start() {
147 return None;
148 }
149
150 let replace_node = replace_node.unwrap_or_else(|| if_expr.syntax().clone());
151 let needs_dedent = replace_node != *if_expr.syntax();
152 let (conds_blocks, tail) = parse_if_chain(if_expr)?;
153
154 acc.add(
155 AssistId::refactor_rewrite("move_arm_cond_to_match_guard"),
156 "Move condition to match guard",
157 replace_node.text_range(),
158 |builder| {
159 let editor = builder.make_editor(match_arm.syntax());
160 let make = editor.make();
161 let mut replace_arms = vec![];
162
163 let dedent = if needs_dedent {
165 cov_mark::hit!(move_guard_ifelse_in_block);
166 1
167 } else {
168 cov_mark::hit!(move_guard_ifelse_else_block);
169 0
170 };
171 let indent_level = match_arm.indent_level();
172 let make_guard = |cond: Option<Expr>| {
173 let condition = match (arm_guard.clone(), cond) {
174 (None, None) => return None,
175 (None, Some(it)) | (Some(it), None) => it,
176 (Some(lhs), Some(rhs)) => {
177 let op_expr = |expr: Expr| {
178 if expr.precedence().needs_parentheses_in(ExprPrecedence::LAnd) {
179 make.expr_paren(expr).into()
180 } else {
181 expr
182 }
183 };
184 let op = syntax::ast::BinaryOp::LogicOp(syntax::ast::LogicOp::And);
185 let expr_bin = make.expr_bin(op_expr(lhs), op, op_expr(rhs));
186 expr_bin.into()
187 }
188 };
189 Some(make.match_guard(condition))
190 };
191
192 for (cond, block) in conds_blocks {
193 let only_expr = block.statements().next().is_none();
194 let expr = match block.tail_expr() {
195 Some(then_expr) if only_expr => then_expr,
196 _ => block.dedent(dedent.into()).into(),
197 };
198 let new_arm = make.match_arm(match_pat.clone(), make_guard(Some(cond)), expr);
199 replace_arms.push(new_arm);
200 }
201 if let Some(block) = tail {
202 cov_mark::hit!(move_guard_ifelse_else_tail);
203 let only_expr = block.statements().next().is_none();
204 let expr = match block.tail_expr() {
205 Some(expr) if only_expr => {
206 cov_mark::hit!(move_guard_ifelse_expr_only);
207 expr
208 }
209 _ => block.dedent(dedent.into()).into(),
210 };
211 let new_arm = make.match_arm(match_pat, make_guard(None), expr);
212 replace_arms.push(new_arm);
213 } else {
214 cov_mark::hit!(move_guard_ifelse_notail);
217 match match_arm.syntax().next_sibling().and_then(MatchArm::cast) {
218 Some(next_arm)
219 if matches!(next_arm.pat(), Some(Pat::WildcardPat(_)))
220 && next_arm.guard().is_none() =>
221 {
222 cov_mark::hit!(move_guard_ifelse_has_wildcard);
223 }
224 _ => {
225 let block_expr = make.expr_empty_block().into();
226 replace_arms.push(make.match_arm(match_pat, make_guard(None), block_expr));
227 }
228 }
229 }
230
231 let newline = make.whitespace(&format!("\n{indent_level}"));
232 let replace_arms = replace_arms.iter().map(|it| it.syntax().syntax_element());
233 let replace_arms = Itertools::intersperse(replace_arms, newline.syntax_element());
234 editor.replace_with_many(match_arm.syntax(), replace_arms.collect());
235
236 builder.add_file_edits(ctx.vfs_file_id(), editor);
237 },
238 )
239}
240
241fn rest_arms(match_arm: &MatchArm, selection: TextRange) -> Option<Vec<MatchArm>> {
242 match_arm
243 .parent_match()
244 .match_arm_list()?
245 .arms()
246 .skip_while(|it| it != match_arm)
247 .skip(1)
248 .take_while(move |it| {
249 selection.is_empty() || crate::utils::is_selected(it, selection, false)
250 })
251 .take_while(move |it| {
252 it.pat()
253 .zip(match_arm.pat())
254 .is_some_and(|(a, b)| a.syntax().text() == b.syntax().text())
255 })
256 .collect::<Vec<_>>()
257 .into()
258}
259
260fn parse_if_chain(if_expr: IfExpr) -> Option<(Vec<(Expr, BlockExpr)>, Option<BlockExpr>)> {
263 let mut conds_blocks = Vec::new();
264 let mut curr_if = if_expr;
265 let tail = loop {
266 let cond = curr_if.condition()?;
267 conds_blocks.push((cond, curr_if.then_branch()?));
268 match curr_if.else_branch() {
269 Some(ElseBranch::IfExpr(e)) => {
270 curr_if = e;
271 }
272 Some(ElseBranch::Block(b)) => {
273 break Some(b);
274 }
275 None => break None,
276 }
277 };
278 Some((conds_blocks, tail))
279}
280
281#[cfg(test)]
282mod tests {
283 use super::*;
284
285 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
286
287 #[test]
288 fn move_guard_to_arm_body_range() {
289 cov_mark::check!(move_guard_inapplicable_in_arm_body);
290 check_assist_not_applicable(
291 move_guard_to_arm_body,
292 r#"
293fn main() {
294 match 92 {
295 x if x > 10 => $0false,
296 _ => true
297 }
298}
299"#,
300 );
301 }
302
303 #[test]
304 fn move_non_naked_arm_cond_to_guard() {
305 cov_mark::check!(move_guard_non_naked_if);
306 check_assist_not_applicable(
307 move_arm_cond_to_match_guard,
308 r#"
309fn main() {
310 match 92 {
311 _ => {
312 let cond = true;
313 $0if cond {
314 foo()
315 }
316 },
317 _ => true
318 }
319}
320"#,
321 );
322 check_assist_not_applicable(
323 move_arm_cond_to_match_guard,
324 r#"
325fn main() {
326 match 92 {
327 _ => {
328 let cond = true;
329 $0if cond {
330 foo()
331 } else {
332 bar()
333 }
334 },
335 _ => true
336 }
337}
338"#,
339 );
340 }
341
342 #[test]
343 fn move_guard_to_arm_body_target() {
344 check_assist_target(
345 move_guard_to_arm_body,
346 r#"
347fn main() {
348 match 92 {
349 x $0if x > 10 => false,
350 _ => true
351 }
352}
353"#,
354 r#"if x > 10"#,
355 );
356 }
357
358 #[test]
359 fn move_guard_to_arm_body_works() {
360 check_assist(
361 move_guard_to_arm_body,
362 r#"
363fn main() {
364 match 92 {
365 x $0if x > 10 => false,
366 _ => true
367 }
368}
369"#,
370 r#"
371fn main() {
372 match 92 {
373 x => if x > 10 {
374 false
375 },
376 _ => true
377 }
378}
379"#,
380 );
381 }
382
383 #[test]
384 fn move_multiple_guard_to_arm_body_works() {
385 check_assist(
386 move_guard_to_arm_body,
387 r#"
388fn main() {
389 match 92 {
390 x @ 0..30 $0if x % 3 == 0 => false,
391 x @ 0..30 if x % 2 == 0 => true,
392 _ => false
393 }
394}
395"#,
396 r#"
397fn main() {
398 match 92 {
399 x @ 0..30 => if x % 3 == 0 {
400 false
401 } else if x % 2 == 0 {
402 true
403 },
404 _ => false
405 }
406}
407"#,
408 );
409
410 check_assist(
411 move_guard_to_arm_body,
412 r#"
413fn main() {
414 match 92 {
415 x @ 0..30 $0if x % 3 == 0 => false,
416 x @ 0..30 if x % 2 == 0 => true,
417 x @ 0..30 => false,
418 _ => true
419 }
420}
421"#,
422 r#"
423fn main() {
424 match 92 {
425 x @ 0..30 => if x % 3 == 0 {
426 false
427 } else if x % 2 == 0 {
428 true
429 } else {
430 false
431 },
432 _ => true
433 }
434}
435"#,
436 );
437
438 check_assist(
439 move_guard_to_arm_body,
440 r#"
441fn main() {
442 match 92 {
443 x @ 0..30 if x % 3 == 0 => false,
444 x @ 0..30 $0if x % 2 == 0$0 => true,
445 x @ 0..30 => false,
446 _ => true
447 }
448}
449"#,
450 r#"
451fn main() {
452 match 92 {
453 x @ 0..30 if x % 3 == 0 => false,
454 x @ 0..30 => if x % 2 == 0 {
455 true
456 },
457 x @ 0..30 => false,
458 _ => true
459 }
460}
461"#,
462 );
463
464 check_assist(
465 move_guard_to_arm_body,
466 r#"
467fn main() {
468 match 92 {
469 x @ 0..30 $0if x % 3 == 0 => false,
470 x @ 0..30 $0if x % 2 == 0 => true,
471 x @ 0..30 => false,
472 _ => true
473 }
474}
475"#,
476 r#"
477fn main() {
478 match 92 {
479 x @ 0..30 => if x % 3 == 0 {
480 false
481 } else if x % 2 == 0 {
482 true
483 },
484 x @ 0..30 => false,
485 _ => true
486 }
487}
488"#,
489 );
490 }
491
492 #[test]
493 fn move_guard_to_block_arm_body_works() {
494 check_assist(
495 move_guard_to_arm_body,
496 r#"
497fn main() {
498 match 92 {
499 x $0if x > 10 => {
500 let _ = true;
501 false
502 },
503 _ => true
504 }
505}
506"#,
507 r#"
508fn main() {
509 match 92 {
510 x => if x > 10 {
511 let _ = true;
512 false
513 },
514 _ => true
515 }
516}
517"#,
518 );
519 }
520
521 #[test]
522 fn move_let_guard_to_arm_body_works() {
523 check_assist(
524 move_guard_to_arm_body,
525 r#"
526fn main() {
527 match 92 {
528 x $0if (let 1 = x) => false,
529 _ => true
530 }
531}
532"#,
533 r#"
534fn main() {
535 match 92 {
536 x => if (let 1 = x) {
537 false
538 },
539 _ => true
540 }
541}
542"#,
543 );
544 }
545
546 #[test]
547 fn move_multiline_guard_to_arm_body_works() {
548 check_assist(
549 move_guard_to_arm_body,
550 r#"
551fn main() {
552 match 92 {
553 x $0if true
554 && true
555 && true =>
556 {
557 {
558 false
559 }
560 },
561 _ => true
562 }
563}
564"#,
565 r#"
566fn main() {
567 match 92 {
568 x => if true
569 && true
570 && true
571 {
572 {
573 false
574 }
575 },
576 _ => true
577 }
578}
579"#,
580 );
581 }
582
583 #[test]
584 fn move_guard_to_arm_body_works_complex_match() {
585 check_assist(
586 move_guard_to_arm_body,
587 r#"
588fn main() {
589 match 92 {
590 $0x @ 4 | x @ 5 if x > 5 => true,
591 _ => false
592 }
593}
594"#,
595 r#"
596fn main() {
597 match 92 {
598 x @ 4 | x @ 5 => if x > 5 {
599 true
600 },
601 _ => false
602 }
603}
604"#,
605 );
606 }
607
608 #[test]
609 fn move_arm_cond_to_match_guard_works() {
610 check_assist(
611 move_arm_cond_to_match_guard,
612 r#"
613fn main() {
614 match 92 {
615 x => if x > 10$0 { false },
616 _ => true
617 }
618}
619"#,
620 r#"
621fn main() {
622 match 92 {
623 x if x > 10 => false,
624 _ => true
625 }
626}
627"#,
628 );
629 }
630
631 #[test]
632 fn move_arm_cond_in_block_to_match_guard_works() {
633 cov_mark::check!(move_guard_ifelse_has_wildcard);
634 check_assist(
635 move_arm_cond_to_match_guard,
636 r#"
637fn main() {
638 match 92 {
639 x => {
640 $0if x > 10 {
641 false
642 }
643 },
644 _ => true
645 }
646}
647"#,
648 r#"
649fn main() {
650 match 92 {
651 x if x > 10 => false,
652 _ => true
653 }
654}
655"#,
656 );
657 }
658
659 #[test]
660 fn move_arm_cond_in_block_to_match_guard_no_wildcard_works() {
661 cov_mark::check_count!(move_guard_ifelse_has_wildcard, 0);
662 check_assist(
663 move_arm_cond_to_match_guard,
664 r#"
665fn main() {
666 match 92 {
667 x => {
668 $0if x > 10 {
669 false
670 }
671 }
672 }
673}
674"#,
675 r#"
676fn main() {
677 match 92 {
678 x if x > 10 => false,
679 x => {}
680 }
681}
682"#,
683 );
684 }
685
686 #[test]
687 fn move_arm_cond_in_block_to_match_guard_wildcard_guard_works() {
688 cov_mark::check_count!(move_guard_ifelse_has_wildcard, 0);
689 check_assist(
690 move_arm_cond_to_match_guard,
691 r#"
692fn main() {
693 match 92 {
694 x => {
695 $0if x > 10 {
696 false
697 }
698 }
699 _ if x > 10 => true,
700 }
701}
702"#,
703 r#"
704fn main() {
705 match 92 {
706 x if x > 10 => false,
707 x => {}
708 _ if x > 10 => true,
709 }
710}
711"#,
712 );
713 }
714
715 #[test]
716 fn move_arm_cond_in_block_to_match_guard_add_comma_works() {
717 check_assist(
718 move_arm_cond_to_match_guard,
719 r#"
720fn main() {
721 match 92 {
722 x => {
723 $0if x > 10 {
724 false
725 }
726 }
727 _ => true
728 }
729}
730"#,
731 r#"
732fn main() {
733 match 92 {
734 x if x > 10 => false,
735 _ => true
736 }
737}
738"#,
739 );
740 }
741
742 #[test]
743 fn move_arm_cond_to_match_guard_if_let_works() {
744 check_assist(
745 move_arm_cond_to_match_guard,
746 r#"
747fn main() {
748 match 92 {
749 x => if let 62 = x $0&& true { false },
750 _ => true
751 }
752}
753"#,
754 r#"
755fn main() {
756 match 92 {
757 x if let 62 = x && true => false,
758 _ => true
759 }
760}
761"#,
762 );
763 }
764
765 #[test]
766 fn move_arm_cond_to_match_guard_if_empty_body_works() {
767 check_assist(
768 move_arm_cond_to_match_guard,
769 r#"
770fn main() {
771 match 92 {
772 x => if x $0> 10 { },
773 _ => true
774 }
775}
776"#,
777 r#"
778fn main() {
779 match 92 {
780 x if x > 10 => { }
781 _ => true
782 }
783}
784"#,
785 );
786 }
787
788 #[test]
789 fn move_arm_cond_to_match_guard_if_multiline_body_works() {
790 check_assist(
791 move_arm_cond_to_match_guard,
792 r#"
793fn main() {
794 match 92 {
795 x => if$0 x > 10 {
796 92;
797 false
798 },
799 _ => true
800 }
801}
802"#,
803 r#"
804fn main() {
805 match 92 {
806 x if x > 10 => {
807 92;
808 false
809 }
810 _ => true
811 }
812}
813"#,
814 );
815 }
816
817 #[test]
818 fn move_arm_cond_in_block_to_match_guard_if_multiline_body_works() {
819 check_assist(
820 move_arm_cond_to_match_guard,
821 r#"
822fn main() {
823 match 92 {
824 x => {
825 if x > $010 {
826 92;
827 false
828 }
829 }
830 _ => true
831 }
832}
833"#,
834 r#"
835fn main() {
836 match 92 {
837 x if x > 10 => {
838 92;
839 false
840 }
841 _ => true
842 }
843}
844"#,
845 )
846 }
847
848 #[test]
849 fn move_arm_cond_to_match_guard_with_else_works() {
850 check_assist(
851 move_arm_cond_to_match_guard,
852 r#"
853fn main() {
854 match 92 {
855 x => if x > $010 {
856 false
857 } else {
858 true
859 }
860 _ => true,
861 }
862}
863"#,
864 r#"
865fn main() {
866 match 92 {
867 x if x > 10 => false,
868 x => true,
869 _ => true,
870 }
871}
872"#,
873 )
874 }
875
876 #[test]
877 fn move_arm_cond_to_match_guard_with_else_block_works() {
878 cov_mark::check!(move_guard_ifelse_expr_only);
879 check_assist(
880 move_arm_cond_to_match_guard,
881 r#"
882fn main() {
883 match 92 {
884 x => {
885 if x $0> 10 {
886 false
887 } else {
888 true
889 }
890 }
891 _ => true
892 }
893}
894"#,
895 r#"
896fn main() {
897 match 92 {
898 x if x > 10 => false,
899 x => true,
900 _ => true
901 }
902}
903"#,
904 )
905 }
906
907 #[test]
908 fn move_arm_cond_to_match_guard_else_if_empty_body_works() {
909 check_assist(
910 move_arm_cond_to_match_guard,
911 r#"
912fn main() {
913 match 92 {
914 x => if x > $010 { } else { },
915 _ => true
916 }
917}
918"#,
919 r#"
920fn main() {
921 match 92 {
922 x if x > 10 => { }
923 x => { }
924 _ => true
925 }
926}
927"#,
928 );
929 }
930
931 #[test]
932 fn move_arm_cond_to_match_guard_with_else_multiline_works() {
933 check_assist(
934 move_arm_cond_to_match_guard,
935 r#"
936fn main() {
937 match 92 {
938 x => if$0 x > 10 {
939 92;
940 false
941 } else {
942 true
943 }
944 _ => true
945 }
946}
947"#,
948 r#"
949fn main() {
950 match 92 {
951 x if x > 10 => {
952 92;
953 false
954 }
955 x => true,
956 _ => true
957 }
958}
959"#,
960 )
961 }
962
963 #[test]
964 fn move_arm_cond_to_match_guard_with_else_multiline_else_works() {
965 cov_mark::check!(move_guard_ifelse_else_block);
966 check_assist(
967 move_arm_cond_to_match_guard,
968 r#"
969fn main() {
970 match 92 {
971 x => if x $0> 10 {
972 false
973 } else {
974 42;
975 true
976 }
977 _ => true
978 }
979}
980"#,
981 r#"
982fn main() {
983 match 92 {
984 x if x > 10 => false,
985 x => {
986 42;
987 true
988 }
989 _ => true
990 }
991}
992"#,
993 )
994 }
995
996 #[test]
997 fn move_arm_cond_to_match_guard_with_else_multiline_else_block_works() {
998 cov_mark::check!(move_guard_ifelse_in_block);
999 check_assist(
1000 move_arm_cond_to_match_guard,
1001 r#"
1002fn main() {
1003 match 92 {
1004 x => {
1005 if x > $010 {
1006 false
1007 } else {
1008 42;
1009 true
1010 }
1011 }
1012 _ => true
1013 }
1014}
1015"#,
1016 r#"
1017fn main() {
1018 match 92 {
1019 x if x > 10 => false,
1020 x => {
1021 42;
1022 true
1023 }
1024 _ => true
1025 }
1026}
1027"#,
1028 )
1029 }
1030
1031 #[test]
1032 fn move_arm_cond_to_match_guard_with_else_last_arm_works() {
1033 check_assist(
1034 move_arm_cond_to_match_guard,
1035 r#"
1036fn main() {
1037 match 92 {
1038 3 => true,
1039 x => {
1040 if x > $010 {
1041 false
1042 } else {
1043 92;
1044 true
1045 }
1046 }
1047 }
1048}
1049"#,
1050 r#"
1051fn main() {
1052 match 92 {
1053 3 => true,
1054 x if x > 10 => false,
1055 x => {
1056 92;
1057 true
1058 }
1059 }
1060}
1061"#,
1062 )
1063 }
1064
1065 #[test]
1066 fn move_arm_cond_to_match_guard_with_else_comma_works() {
1067 check_assist(
1068 move_arm_cond_to_match_guard,
1069 r#"
1070fn main() {
1071 match 92 {
1072 3 => true,
1073 x => if x > $010 {
1074 false
1075 } else {
1076 92;
1077 true
1078 },
1079 }
1080}
1081"#,
1082 r#"
1083fn main() {
1084 match 92 {
1085 3 => true,
1086 x if x > 10 => false,
1087 x => {
1088 92;
1089 true
1090 }
1091 }
1092}
1093"#,
1094 )
1095 }
1096
1097 #[test]
1098 fn move_arm_cond_to_match_guard_elseif() {
1099 check_assist(
1100 move_arm_cond_to_match_guard,
1101 r#"
1102fn main() {
1103 match 92 {
1104 3 => true,
1105 x => if x $0> 10 {
1106 false
1107 } else if x > 5 {
1108 true
1109 } else if x > 4 {
1110 false
1111 } else {
1112 true
1113 },
1114 }
1115}
1116"#,
1117 r#"
1118fn main() {
1119 match 92 {
1120 3 => true,
1121 x if x > 10 => false,
1122 x if x > 5 => true,
1123 x if x > 4 => false,
1124 x => true,
1125 }
1126}
1127"#,
1128 )
1129 }
1130
1131 #[test]
1132 fn move_arm_cond_to_match_guard_elseif_in_block() {
1133 cov_mark::check!(move_guard_ifelse_in_block);
1134 check_assist(
1135 move_arm_cond_to_match_guard,
1136 r#"
1137fn main() {
1138 match 92 {
1139 3 => true,
1140 x => {
1141 if x > $010 {
1142 false
1143 } else if x > 5 {
1144 true
1145 } else if x > 4 {
1146 false
1147 } else {
1148 true
1149 }
1150 }
1151 }
1152}
1153"#,
1154 r#"
1155fn main() {
1156 match 92 {
1157 3 => true,
1158 x if x > 10 => false,
1159 x if x > 5 => true,
1160 x if x > 4 => false,
1161 x => true,
1162 }
1163}
1164"#,
1165 )
1166 }
1167
1168 #[test]
1169 fn move_arm_cond_to_match_guard_elseif_chain() {
1170 cov_mark::check!(move_guard_ifelse_else_tail);
1171 check_assist(
1172 move_arm_cond_to_match_guard,
1173 r#"
1174fn main() {
1175 match 92 {
1176 3 => 0,
1177 x => if x $0> 10 {
1178 1
1179 } else if x > 5 {
1180 2
1181 } else if x > 3 {
1182 42;
1183 3
1184 } else {
1185 4
1186 },
1187 }
1188}
1189"#,
1190 r#"
1191fn main() {
1192 match 92 {
1193 3 => 0,
1194 x if x > 10 => 1,
1195 x if x > 5 => 2,
1196 x if x > 3 => {
1197 42;
1198 3
1199 }
1200 x => 4,
1201 }
1202}
1203"#,
1204 )
1205 }
1206
1207 #[test]
1208 fn move_arm_cond_to_match_guard_elseif_iflet() {
1209 check_assist(
1210 move_arm_cond_to_match_guard,
1211 r#"
1212fn main() {
1213 match 92 {
1214 3 => 0,
1215 x => if x $0> 10 {
1216 1
1217 } else if x > 5 {
1218 2
1219 } else if let 4 = 4 {
1220 42;
1221 3
1222 } else {
1223 4
1224 },
1225 }
1226}"#,
1227 r#"
1228fn main() {
1229 match 92 {
1230 3 => 0,
1231 x if x > 10 => 1,
1232 x if x > 5 => 2,
1233 x if let 4 = 4 => {
1234 42;
1235 3
1236 }
1237 x => 4,
1238 }
1239}"#,
1240 );
1241 }
1242
1243 #[test]
1244 fn move_arm_cond_to_match_guard_elseif_notail() {
1245 cov_mark::check!(move_guard_ifelse_notail);
1246 check_assist(
1247 move_arm_cond_to_match_guard,
1248 r#"
1249fn main() {
1250 match 92 {
1251 3 => 0,
1252 x => if x > $010 {
1253 1
1254 } else if x > 5 {
1255 2
1256 } else if x > 4 {
1257 42;
1258 3
1259 },
1260 }
1261}
1262"#,
1263 r#"
1264fn main() {
1265 match 92 {
1266 3 => 0,
1267 x if x > 10 => 1,
1268 x if x > 5 => 2,
1269 x if x > 4 => {
1270 42;
1271 3
1272 }
1273 x => {}
1274 }
1275}
1276"#,
1277 )
1278 }
1279
1280 #[test]
1281 fn move_arm_cond_to_match_guard_elseif_exist_guard() {
1282 check_assist(
1283 move_arm_cond_to_match_guard,
1284 r#"
1285fn main() {
1286 let cond = true;
1287 match 92 {
1288 3 => true,
1289 x if cond => if x $0> 10 {
1290 false
1291 } else if x > 5 {
1292 true
1293 } else if x > 4 || x < -2 {
1294 false
1295 } else {
1296 true
1297 },
1298 }
1299}
1300"#,
1301 r#"
1302fn main() {
1303 let cond = true;
1304 match 92 {
1305 3 => true,
1306 x if cond && x > 10 => false,
1307 x if cond && x > 5 => true,
1308 x if cond && (x > 4 || x < -2) => false,
1309 x if cond => true,
1310 }
1311}
1312"#,
1313 )
1314 }
1315}