]> git.lizzy.rs Git - rust.git/blobdiff - src/shape.rs
Make children list in-order
[rust.git] / src / shape.rs
index b5d57997e870672dbe3f9de0e177621d99bbdbcb..12a911a19315a583d9a62e733758567725cf7ad9 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::borrow::Cow;
+use std::cmp::min;
 use std::ops::{Add, Sub};
 
 use Config;
@@ -21,11 +23,16 @@ pub struct Indent {
     pub alignment: usize,
 }
 
+// INDENT_BUFFER.len() = 81
+const INDENT_BUFFER_LEN: usize = 80;
+const INDENT_BUFFER: &str =
+    "\n                                                                                ";
+
 impl Indent {
     pub fn new(block_indent: usize, alignment: usize) -> Indent {
         Indent {
-            block_indent: block_indent,
-            alignment: alignment,
+            block_indent,
+            alignment,
         }
     }
 
@@ -68,21 +75,36 @@ pub fn width(&self) -> usize {
         self.block_indent + self.alignment
     }
 
-    pub fn to_string(&self, config: &Config) -> String {
+    pub fn to_string(&self, config: &Config) -> Cow<'static, str> {
+        self.to_string_inner(config, 1)
+    }
+
+    pub fn to_string_with_newline(&self, config: &Config) -> Cow<'static, str> {
+        self.to_string_inner(config, 0)
+    }
+
+    fn to_string_inner(&self, config: &Config, offset: usize) -> Cow<'static, str> {
         let (num_tabs, num_spaces) = if config.hard_tabs() {
             (self.block_indent / config.tab_spaces(), self.alignment)
         } else {
             (0, self.width())
         };
         let num_chars = num_tabs + num_spaces;
-        let mut indent = String::with_capacity(num_chars);
-        for _ in 0..num_tabs {
-            indent.push('\t')
-        }
-        for _ in 0..num_spaces {
-            indent.push(' ')
+        if num_tabs == 0 && num_chars + offset <= INDENT_BUFFER_LEN {
+            Cow::from(&INDENT_BUFFER[offset..num_chars + 1])
+        } else {
+            let mut indent = String::with_capacity(num_chars + if offset == 0 { 1 } else { 0 });
+            if offset == 0 {
+                indent.push('\n');
+            }
+            for _ in 0..num_tabs {
+                indent.push('\t')
+            }
+            for _ in 0..num_spaces {
+                indent.push(' ')
+            }
+            Cow::from(indent)
         }
-        indent
     }
 }
 
@@ -152,38 +174,27 @@ impl Shape {
     //        |<--->|    width
     pub fn legacy(width: usize, indent: Indent) -> Shape {
         Shape {
-            width: width,
-            indent: indent,
+            width,
+            indent,
             offset: indent.alignment,
         }
     }
 
     pub fn indented(indent: Indent, config: &Config) -> Shape {
         Shape {
-            width: config.max_width().checked_sub(indent.width()).unwrap_or(0),
-            indent: indent,
+            width: config.max_width().saturating_sub(indent.width()),
+            indent,
             offset: indent.alignment,
         }
     }
 
     pub fn with_max_width(&self, config: &Config) -> Shape {
         Shape {
-            width: config
-                .max_width()
-                .checked_sub(self.indent.width())
-                .unwrap_or(0),
+            width: config.max_width().saturating_sub(self.indent.width()),
             ..*self
         }
     }
 
-    pub fn offset(width: usize, indent: Indent, offset: usize) -> Shape {
-        Shape {
-            width: width,
-            indent: indent,
-            offset: offset,
-        }
-    }
-
     pub fn visual_indent(&self, extra_width: usize) -> Shape {
         let alignment = self.offset + extra_width;
         Shape {
@@ -253,8 +264,21 @@ pub fn used_width(&self) -> usize {
     pub fn rhs_overhead(&self, config: &Config) -> usize {
         config
             .max_width()
-            .checked_sub(self.used_width() + self.width)
-            .unwrap_or(0)
+            .saturating_sub(self.used_width() + self.width)
+    }
+
+    pub fn comment(&self, config: &Config) -> Shape {
+        let width = min(
+            self.width,
+            config.comment_width().saturating_sub(self.indent.width()),
+        );
+        Shape { width, ..*self }
+    }
+
+    pub fn to_string_with_newline(&self, config: &Config) -> Cow<'static, str> {
+        let mut offset_indent = self.indent;
+        offset_indent.alignment = self.offset;
+        offset_indent.to_string_inner(config, 0)
     }
 }