Skip to main content

rustfmt_nightly/
range.rs

1use crate::expr::{lit_ends_in_dot, rewrite_unary_prefix, rewrite_unary_suffix};
2use crate::pairs::{PairParts, rewrite_pair};
3use crate::rewrite::{RewriteContext, RewriteResult};
4use crate::shape::Shape;
5
6use rustc_ast::ast;
7
8fn needs_space_before_range(context: &RewriteContext<'_>, lhs: &ast::Expr) -> bool {
9    match lhs.kind {
10        ast::ExprKind::Lit(token_lit) => lit_ends_in_dot(&token_lit, context),
11        ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, expr),
12        ast::ExprKind::Binary(_, _, ref rhs_expr) => needs_space_before_range(context, rhs_expr),
13        _ => false,
14    }
15}
16
17fn needs_space_after_range(rhs: &ast::Expr) -> bool {
18    // Don't format `.. ..` into `....`, which is invalid.
19    //
20    // This check is unnecessary for `lhs`, because a range
21    // starting from another range needs parentheses as `(x ..) ..`
22    // (`x .. ..` is a range from `x` to `..`).
23    matches!(rhs.kind, ast::ExprKind::Range(None, _, _))
24}
25
26pub(crate) fn rewrite_range(
27    context: &RewriteContext<'_>,
28    shape: Shape,
29    lhs: Option<&ast::Expr>,
30    rhs: Option<&ast::Expr>,
31    delim: &str,
32) -> RewriteResult {
33    let default_sp_delim = |lhs: Option<&ast::Expr>, rhs: Option<&ast::Expr>| {
34        let space_if = |b: bool| if b { " " } else { "" };
35
36        format!(
37            "{}{}{}",
38            lhs.map_or("", |lhs| space_if(needs_space_before_range(context, lhs))),
39            delim,
40            rhs.map_or("", |rhs| space_if(needs_space_after_range(rhs))),
41        )
42    };
43
44    match (lhs, rhs) {
45        (Some(lhs), Some(rhs)) => {
46            let sp_delim = if context.config.spaces_around_ranges() {
47                format!(" {delim} ")
48            } else {
49                default_sp_delim(Some(lhs), Some(rhs))
50            };
51            rewrite_pair(
52                lhs,
53                rhs,
54                PairParts::infix(&sp_delim),
55                context,
56                shape,
57                context.config.binop_separator(),
58            )
59        }
60        (None, Some(rhs)) => {
61            let sp_delim = if context.config.spaces_around_ranges() {
62                format!("{delim} ")
63            } else {
64                default_sp_delim(None, Some(rhs))
65            };
66            rewrite_unary_prefix(context, &sp_delim, rhs, shape)
67        }
68        (Some(lhs), None) => {
69            let sp_delim = if context.config.spaces_around_ranges() {
70                format!(" {delim}")
71            } else {
72                default_sp_delim(Some(lhs), None)
73            };
74            rewrite_unary_suffix(context, &sp_delim, lhs, shape)
75        }
76        (None, None) => Ok(delim.to_owned()),
77    }
78}