]> git.lizzy.rs Git - rust.git/blobdiff - src/overflow.rs
Format array using overflow module
[rust.git] / src / overflow.rs
index 9d586c0ffa4a442ffc218e0e0973fcaf7cbd5afa..6383d032273bdf4e4bcab637137b8d5ffd9f9417 100644 (file)
 use config::lists::*;
 use syntax::ast;
 use syntax::codemap::Span;
+use syntax::parse::token::DelimToken;
 
 use closures;
 use codemap::SpanUtils;
-use expr::{is_nested_call, maybe_get_args_offset, ToExpr};
+use expr::{is_every_expr_simple, is_nested_call, maybe_get_args_offset, ToExpr};
 use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator};
 use rewrite::{Rewrite, RewriteContext};
 use shape::Shape;
@@ -26,6 +27,8 @@
 
 use std::cmp::min;
 
+const SHORT_ITEM_THRESHOLD: usize = 10;
+
 pub fn rewrite_with_parens<T>(
     context: &RewriteContext,
     ident: &str,
@@ -48,6 +51,7 @@ pub fn rewrite_with_parens<T>(
         ")",
         item_max_width,
         force_separator_tactic,
+        None,
     ).rewrite(shape)
 }
 
@@ -71,6 +75,38 @@ pub fn rewrite_with_angle_brackets<T>(
         ">",
         context.config.max_width(),
         None,
+        None,
+    ).rewrite(shape)
+}
+
+pub fn rewrite_with_square_brackets<T>(
+    context: &RewriteContext,
+    name: &str,
+    items: &[&T],
+    shape: Shape,
+    span: Span,
+    force_separator_tactic: Option<SeparatorTactic>,
+    delim_token: Option<DelimToken>,
+) -> Option<String>
+where
+    T: Rewrite + ToExpr + Spanned,
+{
+    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)
 }
 
@@ -86,6 +122,7 @@ struct Context<'a, T: 'a> {
     item_max_width: usize,
     one_line_width: usize,
     force_separator_tactic: Option<SeparatorTactic>,
+    custom_delims: Option<(&'a str, &'a str)>,
 }
 
 impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> {
@@ -99,6 +136,7 @@ pub fn new(
         suffix: &'static str,
         item_max_width: usize,
         force_separator_tactic: Option<SeparatorTactic>,
+        custom_delims: Option<(&'a str, &'a str)>,
     ) -> Context<'a, T> {
         // 2 = `( `, 1 = `(`
         let paren_overhead = if context.config.spaces_within_parens_and_brackets() {
@@ -135,6 +173,7 @@ pub fn new(
             item_max_width,
             one_line_width,
             force_separator_tactic,
+            custom_delims,
         }
     }
 
@@ -301,6 +340,8 @@ fn try_overflow_last_item(&self, list_items: &mut Vec<ListItem>) -> DefinitiveLi
                             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;
                         }
                     }
                 }
@@ -339,13 +380,20 @@ fn rewrite_items(&self) -> Option<(bool, String)> {
                 tactic
             } else if !self.context.use_block_indent() {
                 SeparatorTactic::Never
+            } else if tactic == DefinitiveListTactic::Mixed {
+                // We are using mixed layout because everything did not fit within a single line.
+                SeparatorTactic::Always
             } else {
                 self.context.config.trailing_comma()
             },
             separator_place: SeparatorPlace::Back,
             shape: self.nested_shape,
-            ends_with_newline: self.context.use_block_indent()
-                && tactic == DefinitiveListTactic::Vertical,
+            ends_with_newline: match tactic {
+                DefinitiveListTactic::Vertical | DefinitiveListTactic::Mixed => {
+                    self.context.use_block_indent()
+                }
+                _ => false,
+            },
             preserve_newline: false,
             config: self.context.config,
         };
@@ -363,6 +411,10 @@ fn wrap_items(&self, items_str: &str, shape: Shape, is_extendable: bool) -> Stri
             ..shape
         };
 
+        let (prefix, suffix) = match self.custom_delims {
+            Some((lhs, rhs)) => (lhs, rhs),
+            _ => (self.prefix, self.suffix),
+        };
         let paren_overhead = paren_overhead(self.context);
         let fits_one_line = items_str.len() + paren_overhead <= shape.width;
         let extend_width = if items_str.is_empty() {
@@ -381,7 +433,7 @@ fn wrap_items(&self, items_str: &str, shape: Shape, is_extendable: bool) -> Stri
             self.ident.len() + items_str.len() + 2 + indent_str.len() + nested_indent_str.len(),
         );
         result.push_str(self.ident);
-        result.push_str(self.prefix);
+        result.push_str(prefix);
         if !self.context.use_block_indent()
             || (self.context.inside_macro() && !items_str.contains('\n') && fits_one_line)
             || (is_extendable && extend_width <= shape.width)
@@ -400,7 +452,7 @@ fn wrap_items(&self, items_str: &str, shape: Shape, is_extendable: bool) -> Stri
             }
             result.push_str(&indent_str);
         }
-        result.push_str(self.suffix);
+        result.push_str(suffix);
         result
     }
 
@@ -488,3 +540,8 @@ fn shape_from_indent_style(
         }
     }
 }
+
+fn no_long_items(list: &[ListItem]) -> bool {
+    list.iter()
+        .all(|item| !item.has_comment() && item.inner_as_ref().len() <= SHORT_ITEM_THRESHOLD)
+}