diff --git a/src/fmt/expr.rs b/src/fmt/expr.rs index 2fb002cc73..4be2ee43d8 100644 --- a/src/fmt/expr.rs +++ b/src/fmt/expr.rs @@ -143,19 +143,27 @@ pub fn fmt_expr<'a>( let mut it = branches.iter().peekable(); while let Some((patterns, expr)) = it.next() { add_spaces(buf, indent + INDENT); + let (first, rest) = patterns.split_first().unwrap(); - match patterns.first().unwrap().value { + match first.value { Pattern::SpaceBefore(nested, spaces) => { fmt_comments_only(buf, spaces.iter(), indent + INDENT); fmt_pattern(buf, nested, indent + INDENT, false); } _ => { - fmt_pattern( - buf, - &patterns.first().unwrap().value, - indent + INDENT, - false, - ); + fmt_pattern(buf, &first.value, indent + INDENT, false); + } + }; + for pattern in rest { + buf.push_str(" | "); + match pattern.value { + Pattern::SpaceBefore(nested, spaces) => { + fmt_comments_only(buf, spaces.iter(), indent + INDENT); + fmt_pattern(buf, nested, indent + INDENT, false); + } + _ => { + fmt_pattern(buf, &pattern.value, indent + INDENT, false); + } } } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index b440283d69..d3578d9d7e 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -870,12 +870,8 @@ pub fn case_branches<'a>( // 1. Parse the first branch and get its indentation level. (It must be >= min_indent.) // 2. Parse the other branches. Their indentation levels must be == the first branch's. - let (mut loc_first_pattern, state) = sep_by1( - // TODO maybe remove these spaces - map!(and!(space1(min_indent), char('|')), |_| ()), - space1_before(loc!(pattern(min_indent)), min_indent), - ) - .parse(arena, state)?; + let (mut loc_first_pattern, state) = + alternative_patterns(min_indent).parse(arena, state)?; let original_indent = state.indent_col; let indented_more = original_indent + 1; let (spaces_before_arrow, state) = space0(min_indent).parse(arena, state)?; @@ -904,10 +900,7 @@ pub fn case_branches<'a>( let branch_parser = and!( then( - sep_by1( - char('|'), - space1_around(loc!(pattern(min_indent)), min_indent), - ), + alternative_patterns(min_indent), move |_arena, state, loc_pattern| { if state.indent_col == original_indent { Ok((loc_pattern, state)) @@ -919,7 +912,7 @@ pub fn case_branches<'a>( }, ), skip_first!( - string("->"), + and!(space1(min_indent), string("->")), space1_before( loc!(move |arena, state| parse_expr(min_indent, arena, state)), min_indent, @@ -945,6 +938,12 @@ pub fn case_branches<'a>( Ok((branches, state)) } } +fn alternative_patterns<'a>(min_indent: u16) -> impl Parser<'a, Vec<'a, Located>>> { + sep_by1( + map!(and!(space1(min_indent), char('|')), |_| ()), + space1_before(loc!(pattern(min_indent)), min_indent), + ) +} pub fn if_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> { map_with_arena!( diff --git a/tests/test_format.rs b/tests/test_format.rs index 2d876899c8..8f3f70c6f1 100644 --- a/tests/test_format.rs +++ b/tests/test_format.rs @@ -1030,6 +1030,39 @@ mod test_format { )); } + #[test] + fn when_with_alternative_patterns() { + expr_formats_same(indoc!( + r#" + when b is + # a comment here + 1 | 2 -> + # a comment there + 1 + "# + )); + } + + #[test] + fn when_with_alternative_patterns_and_spaces() { + expr_formats_to( + indoc!( + r#" + when b is + 1 | 2 | 3 -> + 1 + "# + ), + indoc!( + r#" + when b is + 1 | 2 | 3 -> + 1 + "# + ), + ); + } + #[test] fn when_with_moving_comments() { expr_formats_to(