//! Rewrite a list some items with overflow.

use std::cmp::min;

use itertools::Itertools;
use syntax::parse::token::DelimToken;
use syntax::source_map::Span;
use syntax::{ast, ptr};

use crate::closures;
use crate::config::lists::*;
use crate::config::Version;
use crate::expr::{
    can_be_overflowed_expr, is_every_expr_simple, is_method_call, is_nested_call, is_simple_expr,
    rewrite_cond,
};
use crate::lists::{
    definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
};
use crate::macros::MacroArg;
use crate::patterns::{can_be_overflowed_pat, TuplePatField};
use crate::rewrite::{Rewrite, RewriteContext};
use crate::shape::Shape;
use crate::source_map::SpanUtils;
use crate::spanned::Spanned;
use crate::types::{can_be_overflowed_type, SegmentParam};
use crate::utils::{count_newlines, extra_offset, first_line_width, last_line_width, mk_sp};

const SHORT_ITEM_THRESHOLD: usize = 10;

/// A list of `format!`-like macros, that take a long format string and a list of arguments to
/// format.
///
/// Organized as a list of `(&str, usize)` tuples, giving the name of the macro and the number of
/// arguments before the format string (none for `format!("format", ...)`, one for `assert!(result,
/// "format", ...)`, two for `assert_eq!(left, right, "format", ...)`).
const SPECIAL_MACRO_WHITELIST: &[(&str, usize)] = &[
    // format! like macros
    // From the Rust Standard Library.
    ("eprint!", 0),
    ("eprintln!", 0),
    ("format!", 0),
    ("format_args!", 0),
    ("print!", 0),
    ("println!", 0),
    ("panic!", 0),
    ("unreachable!", 0),
    // From the `log` crate.
    ("debug!", 0),
    ("error!", 0),
    ("info!", 0),
    ("warn!", 0),
    // write! like macros
    ("assert!", 1),
    ("debug_assert!", 1),
    ("write!", 1),
    ("writeln!", 1),
    // assert_eq! like macros
    ("assert_eq!", 2),
    ("assert_ne!", 2),
    ("debug_assert_eq!", 2),
    ("debug_assert_ne!", 2),
];

const SPECIAL_ATTR_WHITELIST: &[(&str, usize)] = &[
    // From the `failure` crate.
    ("fail", 0),
];

#[derive(Debug)]
pub(crate) enum OverflowableItem<'a> {
    Expr(&'a ast::Expr),
    GenericParam(&'a ast::GenericParam),
    MacroArg(&'a MacroArg),
    NestedMetaItem(&'a ast::NestedMetaItem),
    SegmentParam(&'a SegmentParam<'a>),
    StructField(&'a ast::StructField),
    TuplePatField(&'a TuplePatField<'a>),
    Ty(&'a ast::Ty),
}

impl<'a> Rewrite for OverflowableItem<'a> {
    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
        self.map(|item| item.rewrite(context, shape))
    }
}

impl<'a> Spanned for OverflowableItem<'a> {
    fn span(&self) -> Span {
        self.map(|item| item.span())
    }
}

impl<'a> OverflowableItem<'a> {
    fn has_attrs(&self) -> bool {
        match self {
            OverflowableItem::Expr(ast::Expr { attrs, .. })
            | OverflowableItem::GenericParam(ast::GenericParam { attrs, .. }) => !attrs.is_empty(),
            OverflowableItem::StructField(ast::StructField { attrs, .. }) => !attrs.is_empty(),
            OverflowableItem::MacroArg(MacroArg::Expr(expr)) => !expr.attrs.is_empty(),
            OverflowableItem::MacroArg(MacroArg::Item(item)) => !item.attrs.is_empty(),
            _ => false,
        }
    }

    pub(crate) fn map<F, T>(&self, f: F) -> T
    where
        F: Fn(&dyn IntoOverflowableItem<'a>) -> T,
    {
        match self {
            OverflowableItem::Expr(expr) => f(*expr),
            OverflowableItem::GenericParam(gp) => f(*gp),
            OverflowableItem::MacroArg(macro_arg) => f(*macro_arg),
            OverflowableItem::NestedMetaItem(nmi) => f(*nmi),
            OverflowableItem::SegmentParam(sp) => f(*sp),
            OverflowableItem::StructField(sf) => f(*sf),
            OverflowableItem::TuplePatField(pat) => f(*pat),
            OverflowableItem::Ty(ty) => f(*ty),
        }
    }

    pub(crate) fn is_simple(&self) -> bool {
        match self {
            OverflowableItem::Expr(expr) => is_simple_expr(expr),
            OverflowableItem::MacroArg(MacroArg::Keyword(..)) => true,
            OverflowableItem::MacroArg(MacroArg::Expr(expr)) => is_simple_expr(expr),
            OverflowableItem::NestedMetaItem(nested_meta_item) => match nested_meta_item {
                ast::NestedMetaItem::Literal(..) => true,
                ast::NestedMetaItem::MetaItem(ref meta_item) => match meta_item.kind {
                    ast::MetaItemKind::Word => true,
                    _ => false,
                },
            },
            _ => false,
        }
    }

    pub(crate) fn is_expr(&self) -> bool {
        match self {
            OverflowableItem::Expr(..) => true,
            OverflowableItem::MacroArg(MacroArg::Expr(..)) => true,
            _ => false,
        }
    }

    pub(crate) fn is_nested_call(&self) -> bool {
        match self {
            OverflowableItem::Expr(expr) => is_nested_call(expr),
            OverflowableItem::MacroArg(MacroArg::Expr(expr)) => is_nested_call(expr),
            _ => false,
        }
    }

    pub(crate) fn to_expr(&self) -> Option<&'a ast::Expr> {
        match self {
            OverflowableItem::Expr(expr) => Some(expr),
            OverflowableItem::MacroArg(macro_arg) => match macro_arg {
                MacroArg::Expr(ref expr) => Some(expr),
                _ => None,
            },
            _ => None,
        }
    }

    pub(crate) fn can_be_overflowed(&self, context: &RewriteContext<'_>, len: usize) -> bool {
        match self {
            OverflowableItem::Expr(expr) => can_be_overflowed_expr(context, expr, len),
            OverflowableItem::MacroArg(macro_arg) => match macro_arg {
                MacroArg::Expr(ref expr) => can_be_overflowed_expr(context, expr, len),
                MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
                MacroArg::Pat(..) => false,
                MacroArg::Item(..) => len == 1,
                MacroArg::Keyword(..) => false,
            },
            OverflowableItem::NestedMetaItem(nested_meta_item) if len == 1 => {
                match nested_meta_item {
                    ast::NestedMetaItem::Literal(..) => false,
                    ast::NestedMetaItem::MetaItem(..) => true,
                }
            }
            OverflowableItem::SegmentParam(seg) => match seg {
                SegmentParam::Type(ty) => can_be_overflowed_type(context, ty, len),
                _ => false,
            },
            OverflowableItem::TuplePatField(pat) => can_be_overflowed_pat(context, pat, len),
            OverflowableItem::Ty(ty) => can_be_overflowed_type(context, ty, len),
            _ => false,
        }
    }

    fn whitelist(&self) -> &'static [(&'static str, usize)] {
        match self {
            OverflowableItem::MacroArg(..) => SPECIAL_MACRO_WHITELIST,
            OverflowableItem::NestedMetaItem(..) => SPECIAL_ATTR_WHITELIST,
            _ => &[],
        }
    }
}

pub(crate) trait IntoOverflowableItem<'a>: Rewrite + Spanned {
    fn into_overflowable_item(&'a self) -> OverflowableItem<'a>;
}

impl<'a, T: 'a + IntoOverflowableItem<'a>> IntoOverflowableItem<'a> for ptr::P<T> {
    fn into_overflowable_item(&'a self) -> OverflowableItem<'a> {
        (**self).into_overflowable_item()
    }
}

macro_rules! impl_into_overflowable_item_for_ast_node {
    ($($ast_node:ident),*) => {
        $(
            impl<'a> IntoOverflowableItem<'a> for ast::$ast_node {
                fn into_overflowable_item(&'a self) -> OverflowableItem<'a> {
                    OverflowableItem::$ast_node(self)
                }
            }
        )*
    }
}

macro_rules! impl_into_overflowable_item_for_rustfmt_types {
    ([$($ty:ident),*], [$($ty_with_lifetime:ident),*]) => {
        $(
            impl<'a> IntoOverflowableItem<'a> for $ty {
                fn into_overflowable_item(&'a self) -> OverflowableItem<'a> {
                    OverflowableItem::$ty(self)
                }
            }
        )*
        $(
            impl<'a> IntoOverflowableItem<'a> for $ty_with_lifetime<'a> {
                fn into_overflowable_item(&'a self) -> OverflowableItem<'a> {
                    OverflowableItem::$ty_with_lifetime(self)
                }
            }
        )*
    }
}

impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, StructField, Ty);
impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]);

pub(crate) fn into_overflowable_list<'a, T>(
    iter: impl Iterator<Item = &'a T>,
) -> impl Iterator<Item = OverflowableItem<'a>>
where
    T: 'a + IntoOverflowableItem<'a>,
{
    iter.map(|x| IntoOverflowableItem::into_overflowable_item(x))
}

pub(crate) fn rewrite_with_parens<'a, T: 'a + IntoOverflowableItem<'a>>(
    context: &'a RewriteContext<'_>,
    ident: &'a str,
    items: impl Iterator<Item = &'a T>,
    shape: Shape,
    span: Span,
    item_max_width: usize,
    force_separator_tactic: Option<SeparatorTactic>,
) -> Option<String> {
    Context::new(
        context,
        items,
        ident,
        shape,
        span,
        "(",
        ")",
        item_max_width,
        force_separator_tactic,
        None,
    )
    .rewrite(shape)
}

pub(crate) fn rewrite_with_angle_brackets<'a, T: 'a + IntoOverflowableItem<'a>>(
    context: &'a RewriteContext<'_>,
    ident: &'a str,
    items: impl Iterator<Item = &'a T>,
    shape: Shape,
    span: Span,
) -> Option<String> {
    Context::new(
        context,
        items,
        ident,
        shape,
        span,
        "<",
        ">",
        context.config.max_width(),
        None,
        None,
    )
    .rewrite(shape)
}

pub(crate) fn rewrite_with_square_brackets<'a, T: 'a + IntoOverflowableItem<'a>>(
    context: &'a RewriteContext<'_>,
    name: &'a str,
    items: impl Iterator<Item = &'a T>,
    shape: Shape,
    span: Span,
    force_separator_tactic: Option<SeparatorTactic>,
    delim_token: Option<DelimToken>,
) -> Option<String> {
    let (lhs, rhs) = match delim_token {
        Some(DelimToken::Paren) => ("(", ")"),
        Some(DelimToken::Brace) => ("{", "}"),
        _ => ("[", "]"),
    };
    Context::new(
        context,
        items,
        name,
        shape,
        span,
        lhs,
        rhs,
        context.config.width_heuristics().array_width,
        force_separator_tactic,
        Some(("[", "]")),
    )
    .rewrite(shape)
}

struct Context<'a> {
    context: &'a RewriteContext<'a>,
    items: Vec<OverflowableItem<'a>>,
    ident: &'a str,
    prefix: &'static str,
    suffix: &'static str,
    one_line_shape: Shape,
    nested_shape: Shape,
    span: Span,
    item_max_width: usize,
    one_line_width: usize,
    force_separator_tactic: Option<SeparatorTactic>,
    custom_delims: Option<(&'a str, &'a str)>,
}

impl<'a> Context<'a> {
    fn new<T: 'a + IntoOverflowableItem<'a>>(
        context: &'a RewriteContext<'_>,
        items: impl Iterator<Item = &'a T>,
        ident: &'a str,
        shape: Shape,
        span: Span,
        prefix: &'static str,
        suffix: &'static str,
        item_max_width: usize,
        force_separator_tactic: Option<SeparatorTactic>,
        custom_delims: Option<(&'a str, &'a str)>,
    ) -> Context<'a> {
        let used_width = extra_offset(ident, shape);
        // 1 = `()`
        let one_line_width = shape.width.saturating_sub(used_width + 2);

        // 1 = "(" or ")"
        let one_line_shape = shape
            .offset_left(last_line_width(ident) + 1)
            .and_then(|shape| shape.sub_width(1))
            .unwrap_or(Shape { width: 0, ..shape });
        let nested_shape = shape_from_indent_style(context, shape, used_width + 2, used_width + 1);
        Context {
            context,
            items: into_overflowable_list(items).collect(),
            ident,
            one_line_shape,
            nested_shape,
            span,
            prefix,
            suffix,
            item_max_width,
            one_line_width,
            force_separator_tactic,
            custom_delims,
        }
    }

    fn last_item(&self) -> Option<&OverflowableItem<'_>> {
        self.items.last()
    }

    fn items_span(&self) -> Span {
        let span_lo = self
            .context
            .snippet_provider
            .span_after(self.span, self.prefix);
        mk_sp(span_lo, self.span.hi())
    }

    fn rewrite_last_item_with_overflow(
        &self,
        last_list_item: &mut ListItem,
        shape: Shape,
    ) -> Option<String> {
        let last_item = self.last_item()?;
        let rewrite = match last_item {
            OverflowableItem::Expr(ref expr) => {
                match expr.kind {
                    // When overflowing the closure which consists of a single control flow
                    // expression, force to use block if its condition uses multi line.
                    ast::ExprKind::Closure(..) => {
                        // If the argument consists of multiple closures, we do not overflow
                        // the last closure.
                        if closures::args_have_many_closure(&self.items) {
                            None
                        } else {
                            closures::rewrite_last_closure(self.context, expr, shape)
                        }
                    }

                    // When overflowing the expressions which consists of a control flow
                    // expression, avoid condition to use multi line.
                    ast::ExprKind::If(..)
                    | ast::ExprKind::ForLoop(..)
                    | ast::ExprKind::Loop(..)
                    | ast::ExprKind::While(..)
                    | ast::ExprKind::Match(..) => {
                        let multi_line = rewrite_cond(self.context, expr, shape)
                            .map_or(false, |cond| cond.contains('\n'));

                        if multi_line {
                            None
                        } else {
                            expr.rewrite(self.context, shape)
                        }
                    }

                    _ => expr.rewrite(self.context, shape),
                }
            }
            item => item.rewrite(self.context, shape),
        };

        if let Some(rewrite) = rewrite {
            // splitn(2, *).next().unwrap() is always safe.
            let rewrite_first_line = Some(rewrite.splitn(2, '\n').next().unwrap().to_owned());
            last_list_item.item = rewrite_first_line;
            Some(rewrite)
        } else {
            None
        }
    }

    fn default_tactic(&self, list_items: &[ListItem]) -> DefinitiveListTactic {
        definitive_tactic(
            list_items,
            ListTactic::LimitedHorizontalVertical(self.item_max_width),
            Separator::Comma,
            self.one_line_width,
        )
    }

    fn try_overflow_last_item(&self, list_items: &mut Vec<ListItem>) -> DefinitiveListTactic {
        // 1 = "("
        let combine_arg_with_callee = self.items.len() == 1
            && self.items[0].is_expr()
            && !self.items[0].has_attrs()
            && self.ident.len() < self.context.config.tab_spaces();
        let overflow_last = combine_arg_with_callee || can_be_overflowed(self.context, &self.items);

        // Replace the last item with its first line to see if it fits with
        // first arguments.
        let placeholder = if overflow_last {
            let old_value = self.context.force_one_line_chain.get();
            match self.last_item() {
                Some(OverflowableItem::Expr(expr))
                    if !combine_arg_with_callee && is_method_call(expr) =>
                {
                    self.context.force_one_line_chain.replace(true);
                }
                Some(OverflowableItem::MacroArg(MacroArg::Expr(expr)))
                    if !combine_arg_with_callee
                        && is_method_call(expr)
                        && self.context.config.version() == Version::Two =>
                {
                    self.context.force_one_line_chain.replace(true);
                }
                _ => (),
            }
            let result = last_item_shape(
                &self.items,
                list_items,
                self.one_line_shape,
                self.item_max_width,
            )
            .and_then(|arg_shape| {
                self.rewrite_last_item_with_overflow(
                    &mut list_items[self.items.len() - 1],
                    arg_shape,
                )
            });
            self.context.force_one_line_chain.replace(old_value);
            result
        } else {
            None
        };

        let mut tactic = definitive_tactic(
            &*list_items,
            ListTactic::LimitedHorizontalVertical(self.item_max_width),
            Separator::Comma,
            self.one_line_width,
        );

        // Replace the stub with the full overflowing last argument if the rewrite
        // succeeded and its first line fits with the other arguments.
        match (overflow_last, tactic, placeholder) {
            (true, DefinitiveListTactic::Horizontal, Some(ref overflowed))
                if self.items.len() == 1 =>
            {
                // When we are rewriting a nested function call, we restrict the
                // budget for the inner function to avoid them being deeply nested.
                // However, when the inner function has a prefix or a suffix
                // (e.g., `foo() as u32`), this budget reduction may produce poorly
                // formatted code, where a prefix or a suffix being left on its own
                // line. Here we explicitlly check those cases.
                if count_newlines(overflowed) == 1 {
                    let rw = self
                        .items
                        .last()
                        .and_then(|last_item| last_item.rewrite(self.context, self.nested_shape));
                    let no_newline = rw.as_ref().map_or(false, |s| !s.contains('\n'));
                    if no_newline {
                        list_items[self.items.len() - 1].item = rw;
                    } else {
                        list_items[self.items.len() - 1].item = Some(overflowed.to_owned());
                    }
                } else {
                    list_items[self.items.len() - 1].item = Some(overflowed.to_owned());
                }
            }
            (true, DefinitiveListTactic::Horizontal, placeholder @ Some(..)) => {
                list_items[self.items.len() - 1].item = placeholder;
            }
            _ if !self.items.is_empty() => {
                list_items[self.items.len() - 1].item = self
                    .items
                    .last()
                    .and_then(|last_item| last_item.rewrite(self.context, self.nested_shape));

                // Use horizontal layout for a function with a single argument as long as
                // everything fits in a single line.
                // `self.one_line_width == 0` means vertical layout is forced.
                if self.items.len() == 1
                    && self.one_line_width != 0
                    && !list_items[0].has_comment()
                    && !list_items[0].inner_as_ref().contains('\n')
                    && crate::lists::total_item_width(&list_items[0]) <= self.one_line_width
                {
                    tactic = DefinitiveListTactic::Horizontal;
                } else {
                    tactic = self.default_tactic(list_items);

                    if tactic == DefinitiveListTactic::Vertical {
                        if let Some((all_simple, num_args_before)) =
                            maybe_get_args_offset(self.ident, &self.items)
                        {
                            let one_line = all_simple
                                && definitive_tactic(
                                    &list_items[..num_args_before],
                                    ListTactic::HorizontalVertical,
                                    Separator::Comma,
                                    self.nested_shape.width,
                                ) == DefinitiveListTactic::Horizontal
                                && definitive_tactic(
                                    &list_items[num_args_before + 1..],
                                    ListTactic::HorizontalVertical,
                                    Separator::Comma,
                                    self.nested_shape.width,
                                ) == DefinitiveListTactic::Horizontal;

                            if one_line {
                                tactic = DefinitiveListTactic::SpecialMacro(num_args_before);
                            };
                        } else if is_every_expr_simple(&self.items) && no_long_items(list_items) {
                            tactic = DefinitiveListTactic::Mixed;
                        }
                    }
                }
            }
            _ => (),
        }

        tactic
    }

    fn rewrite_items(&self) -> Option<(bool, String)> {
        let span = self.items_span();
        let items = itemize_list(
            self.context.snippet_provider,
            self.items.iter(),
            self.suffix,
            ",",
            |item| item.span().lo(),
            |item| item.span().hi(),
            |item| item.rewrite(self.context, self.nested_shape),
            span.lo(),
            span.hi(),
            true,
        );
        let mut list_items: Vec<_> = items.collect();

        // Try letting the last argument overflow to the next line with block
        // indentation. If its first line fits on one line with the other arguments,
        // we format the function arguments horizontally.
        let tactic = self.try_overflow_last_item(&mut list_items);
        let trailing_separator = if let Some(tactic) = self.force_separator_tactic {
            tactic
        } else if !self.context.use_block_indent() {
            SeparatorTactic::Never
        } else {
            self.context.config.trailing_comma()
        };
        let ends_with_newline = match tactic {
            DefinitiveListTactic::Vertical | DefinitiveListTactic::Mixed => {
                self.context.use_block_indent()
            }
            _ => false,
        };

        let fmt = ListFormatting::new(self.nested_shape, self.context.config)
            .tactic(tactic)
            .trailing_separator(trailing_separator)
            .ends_with_newline(ends_with_newline);

        write_list(&list_items, &fmt)
            .map(|items_str| (tactic == DefinitiveListTactic::Horizontal, items_str))
    }

    fn wrap_items(&self, items_str: &str, shape: Shape, is_extendable: bool) -> String {
        let shape = Shape {
            width: shape.width.saturating_sub(last_line_width(self.ident)),
            ..shape
        };

        let (prefix, suffix) = match self.custom_delims {
            Some((lhs, rhs)) => (lhs, rhs),
            _ => (self.prefix, self.suffix),
        };

        let extend_width = if items_str.is_empty() {
            2
        } else {
            first_line_width(items_str) + 1
        };
        let nested_indent_str = self
            .nested_shape
            .indent
            .to_string_with_newline(self.context.config);
        let indent_str = shape
            .block()
            .indent
            .to_string_with_newline(self.context.config);
        let mut result = String::with_capacity(
            self.ident.len() + items_str.len() + 2 + indent_str.len() + nested_indent_str.len(),
        );
        result.push_str(self.ident);
        result.push_str(prefix);
        let force_single_line = if self.context.config.version() == Version::Two {
            !self.context.use_block_indent() || (is_extendable && extend_width <= shape.width)
        } else {
            // 2 = `()`
            let fits_one_line = items_str.len() + 2 <= shape.width;
            !self.context.use_block_indent()
                || (self.context.inside_macro() && !items_str.contains('\n') && fits_one_line)
                || (is_extendable && extend_width <= shape.width)
        };
        if force_single_line {
            result.push_str(items_str);
        } else {
            if !items_str.is_empty() {
                result.push_str(&nested_indent_str);
                result.push_str(items_str);
            }
            result.push_str(&indent_str);
        }
        result.push_str(suffix);
        result
    }

    fn rewrite(&self, shape: Shape) -> Option<String> {
        let (extendable, items_str) = self.rewrite_items()?;

        // If we are using visual indent style and failed to format, retry with block indent.
        if !self.context.use_block_indent()
            && need_block_indent(&items_str, self.nested_shape)
            && !extendable
        {
            self.context.use_block.replace(true);
            let result = self.rewrite(shape);
            self.context.use_block.replace(false);
            return result;
        }

        Some(self.wrap_items(&items_str, shape, extendable))
    }
}

fn need_block_indent(s: &str, shape: Shape) -> bool {
    s.lines().skip(1).any(|s| {
        s.find(|c| !char::is_whitespace(c))
            .map_or(false, |w| w + 1 < shape.indent.width())
    })
}

fn can_be_overflowed(context: &RewriteContext<'_>, items: &[OverflowableItem<'_>]) -> bool {
    items
        .last()
        .map_or(false, |x| x.can_be_overflowed(context, items.len()))
}

/// Returns a shape for the last argument which is going to be overflowed.
fn last_item_shape(
    lists: &[OverflowableItem<'_>],
    items: &[ListItem],
    shape: Shape,
    args_max_width: usize,
) -> Option<Shape> {
    if items.len() == 1 && !lists.get(0)?.is_nested_call() {
        return Some(shape);
    }
    let offset = items
        .iter()
        .dropping_back(1)
        .map(|i| {
            // 2 = ", "
            2 + i.inner_as_ref().len()
        })
        .sum();
    Shape {
        width: min(args_max_width, shape.width),
        ..shape
    }
    .offset_left(offset)
}

fn shape_from_indent_style(
    context: &RewriteContext<'_>,
    shape: Shape,
    overhead: usize,
    offset: usize,
) -> Shape {
    let (shape, overhead) = if context.use_block_indent() {
        let shape = shape
            .block()
            .block_indent(context.config.tab_spaces())
            .with_max_width(context.config);
        (shape, 1) // 1 = ","
    } else {
        (shape.visual_indent(offset), overhead)
    };
    Shape {
        width: shape.width.saturating_sub(overhead),
        ..shape
    }
}

fn no_long_items(list: &[ListItem]) -> bool {
    list.iter()
        .all(|item| item.inner_as_ref().len() <= SHORT_ITEM_THRESHOLD)
}

/// In case special-case style is required, returns an offset from which we start horizontal layout.
pub(crate) fn maybe_get_args_offset(
    callee_str: &str,
    args: &[OverflowableItem<'_>],
) -> Option<(bool, usize)> {
    if let Some(&(_, num_args_before)) = args
        .get(0)?
        .whitelist()
        .iter()
        .find(|&&(s, _)| s == callee_str)
    {
        let all_simple = args.len() > num_args_before
            && is_every_expr_simple(&args[0..num_args_before])
            && is_every_expr_simple(&args[num_args_before + 1..]);

        Some((all_simple, num_args_before))
    } else {
        None
    }
}
