Browse Source

Make struct for all tree parameters

The fields for ‘depth’ and ‘last’ were being passed around separately, but were always used together.
Benjamin Sago 8 years ago
parent
commit
8453f45f99
3 changed files with 73 additions and 70 deletions
  1. 23 43
      src/output/details.rs
  2. 2 1
      src/output/grid_details.rs
  3. 48 26
      src/output/tree.rs

+ 23 - 43
src/output/details.rs

@@ -70,7 +70,7 @@ use options::{FileFilter, RecurseOptions};
 use output::colours::Colours;
 use output::colours::Colours;
 use output::column::Columns;
 use output::column::Columns;
 use output::cell::TextCell;
 use output::cell::TextCell;
-use output::tree::TreeTrunk;
+use output::tree::{TreeTrunk, TreeParams};
 use output::file_name::{FileName, LinkStyle, Classify};
 use output::file_name::{FileName, LinkStyle, Classify};
 use output::table::{Table, Environment, Row as TableRow};
 use output::table::{Table, Environment, Row as TableRow};
 
 
@@ -233,10 +233,9 @@ impl<'a> Render<'a> {
             }
             }
 
 
             let row = Row {
             let row = Row {
-                depth:    depth,
-                cells:    egg.table_row,
-                name:     FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, self.colours).paint().promote(),
-                last:     index == num_eggs - 1,
+                tree:   TreeParams::new(depth, index == num_eggs - 1),
+                cells:  egg.table_row,
+                name:   FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, self.colours).paint().promote(),
             };
             };
 
 
             rows.push(row);
             rows.push(row);
@@ -253,11 +252,11 @@ impl<'a> Render<'a> {
 
 
                 if !files.is_empty() {
                 if !files.is_empty() {
                     for xattr in egg.xattrs {
                     for xattr in egg.xattrs {
-                        rows.push(self.render_xattr(xattr, depth + 1, false));
+                        rows.push(self.render_xattr(xattr, TreeParams::new(depth + 1, false)));
                     }
                     }
 
 
                     for (error, path) in errors {
                     for (error, path) in errors {
-                        rows.push(self.render_error(&error, depth + 1, false, path));
+                        rows.push(self.render_error(&error, TreeParams::new(depth + 1, false), path));
                     }
                     }
 
 
                     self.add_files_to_table(table, rows, &files, depth + 1);
                     self.add_files_to_table(table, rows, &files, depth + 1);
@@ -267,55 +266,41 @@ impl<'a> Render<'a> {
 
 
             let count = egg.xattrs.len();
             let count = egg.xattrs.len();
             for (index, xattr) in egg.xattrs.into_iter().enumerate() {
             for (index, xattr) in egg.xattrs.into_iter().enumerate() {
-                rows.push(self.render_xattr(xattr, depth + 1, errors.is_empty() && index == count - 1));
+                rows.push(self.render_xattr(xattr, TreeParams::new(depth + 1, errors.is_empty() && index == count - 1)));
             }
             }
 
 
             let count = errors.len();
             let count = errors.len();
             for (index, (error, path)) in errors.into_iter().enumerate() {
             for (index, (error, path)) in errors.into_iter().enumerate() {
-                rows.push(self.render_error(&error, depth + 1, index == count - 1, path));
+                rows.push(self.render_error(&error, TreeParams::new(depth + 1, index == count - 1), path));
             }
             }
         }
         }
     }
     }
 
 
     pub fn render_header(&self, header: TableRow) -> Row {
     pub fn render_header(&self, header: TableRow) -> Row {
         Row {
         Row {
-            depth:    0,
+            tree:     TreeParams::new(0, false),
             cells:    Some(header),
             cells:    Some(header),
             name:     TextCell::paint_str(self.colours.header, "Name"),
             name:     TextCell::paint_str(self.colours.header, "Name"),
-            last:     false,
         }
         }
     }
     }
 
 
-    fn render_error(&self, error: &IOError, depth: usize, last: bool, path: Option<PathBuf>) -> Row {
+    fn render_error(&self, error: &IOError, tree: TreeParams, path: Option<PathBuf>) -> Row {
         let error_message = match path {
         let error_message = match path {
             Some(path) => format!("<{}: {}>", path.display(), error),
             Some(path) => format!("<{}: {}>", path.display(), error),
             None       => format!("<{}>", error),
             None       => format!("<{}>", error),
         };
         };
 
 
-        Row {
-            depth:    depth,
-            cells:    None,
-            name:     TextCell::paint(self.colours.broken_arrow, error_message),
-            last:     last,
-        }
+        let name = TextCell::paint(self.colours.broken_arrow, error_message);
+        Row { cells: None, name, tree }
     }
     }
 
 
-    fn render_xattr(&self, xattr: Attribute, depth: usize, last: bool) -> Row {
-        Row {
-            depth:    depth,
-            cells:    None,
-            name:     TextCell::paint(self.colours.perms.attribute, format!("{} (len {})", xattr.name, xattr.size)),
-            last:     last,
-        }
+    fn render_xattr(&self, xattr: Attribute, tree: TreeParams) -> Row {
+        let name = TextCell::paint(self.colours.perms.attribute, format!("{} (len {})", xattr.name, xattr.size));
+        Row { cells: None, name, tree }
     }
     }
 
 
-    pub fn render_file(&self, cells: TableRow, name_cell: TextCell, depth: usize, last: bool) -> Row {
-        Row {
-            depth:  depth,
-            cells:  Some(cells),
-            name:   name_cell,
-            last:   last,
-        }
+    pub fn render_file(&self, cells: TableRow, name: TextCell, tree: TreeParams) -> Row {
+        Row { cells: Some(cells), name, tree }
     }
     }
 
 
     pub fn iterate_with_table(&'a self, table: Table<'a>, rows: Vec<Row>) -> TableIter<'a> {
     pub fn iterate_with_table(&'a self, table: Table<'a>, rows: Vec<Row>) -> TableIter<'a> {
@@ -360,13 +345,13 @@ impl<'a> Iterator for TableIter<'a> {
                     cell
                     cell
                 };
                 };
 
 
-            for tree_part in self.tree_trunk.new_row(row.depth, row.last) {
+            for tree_part in self.tree_trunk.new_row(row.tree) {
                 cell.push(self.colours.punctuation.paint(tree_part.ascii_art()), 4);
                 cell.push(self.colours.punctuation.paint(tree_part.ascii_art()), 4);
             }
             }
 
 
             // If any tree characters have been printed, then add an extra
             // If any tree characters have been printed, then add an extra
             // space, which makes the output look much better.
             // space, which makes the output look much better.
-            if row.depth != 0 {
+            if !row.tree.is_zero() {
                 cell.add_spaces(1);
                 cell.add_spaces(1);
             }
             }
 
 
@@ -390,13 +375,8 @@ pub struct Row {
     /// from the other cells, as it never requires padding.
     /// from the other cells, as it never requires padding.
     pub name: TextCell,
     pub name: TextCell,
 
 
-    /// How many directories deep into the tree structure this is. Directories
-    /// on top have depth 0.
-    pub depth: usize,
-
-    /// Whether this is the last entry in the directory. This flag is used
-    /// when calculating the tree view.
-    pub last: bool,
+    /// Information used to determine which symbols to display in a tree.
+    pub tree: TreeParams,
 }
 }
 
 
 
 
@@ -414,13 +394,13 @@ impl<'a> Iterator for Iter<'a> {
         self.inner.next().map(|row| {
         self.inner.next().map(|row| {
             let mut cell = TextCell::default();
             let mut cell = TextCell::default();
 
 
-            for tree_part in self.tree_trunk.new_row(row.depth, row.last) {
+            for tree_part in self.tree_trunk.new_row(row.tree) {
                 cell.push(self.colours.punctuation.paint(tree_part.ascii_art()), 4);
                 cell.push(self.colours.punctuation.paint(tree_part.ascii_art()), 4);
             }
             }
 
 
             // If any tree characters have been printed, then add an extra
             // If any tree characters have been printed, then add an extra
             // space, which makes the output look much better.
             // space, which makes the output look much better.
-            if row.depth != 0 {
+            if !row.tree.is_zero() {
                 cell.add_spaces(1);
                 cell.add_spaces(1);
             }
             }
 
 

+ 2 - 1
src/output/grid_details.rs

@@ -14,6 +14,7 @@ use output::details::{Options as DetailsOptions, Row as DetailsRow, Render as De
 use output::grid::Options as GridOptions;
 use output::grid::Options as GridOptions;
 use output::file_name::{FileName, LinkStyle, Classify};
 use output::file_name::{FileName, LinkStyle, Classify};
 use output::table::{Table, Environment, Row as TableRow};
 use output::table::{Table, Environment, Row as TableRow};
+use output::tree::TreeParams;
 
 
 
 
 pub struct Render<'a> {
 pub struct Render<'a> {
@@ -119,7 +120,7 @@ impl<'a> Render<'a> {
 
 
             let (ref mut table, ref mut rows) = tables[index];
             let (ref mut table, ref mut rows) = tables[index];
             table.add_widths(&row);
             table.add_widths(&row);
-            let details_row = drender.render_file(row, file_name.clone(), 0, false);
+            let details_row = drender.render_file(row, file_name.clone(), TreeParams::new(0, false));
             rows.push(details_row);
             rows.push(details_row);
         }
         }
 
 

+ 48 - 26
src/output/tree.rs

@@ -38,6 +38,7 @@
 //! successfully `stat`ted, we don’t know how many files are going to exist in
 //! successfully `stat`ted, we don’t know how many files are going to exist in
 //! each directory)
 //! each directory)
 
 
+
 #[derive(PartialEq, Debug, Clone)]
 #[derive(PartialEq, Debug, Clone)]
 pub enum TreePart {
 pub enum TreePart {
 
 
@@ -79,7 +80,18 @@ pub struct TreeTrunk {
     stack: Vec<TreePart>,
     stack: Vec<TreePart>,
 
 
     /// A tuple for the last ‘depth’ and ‘last’ parameters that are passed in.
     /// A tuple for the last ‘depth’ and ‘last’ parameters that are passed in.
-    last_params: Option<(usize, bool)>,
+    last_params: Option<TreeParams>,
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct TreeParams {
+
+    /// How many directories deep into the tree structure this is. Directories
+    /// on top have depth 0.
+    depth: usize,
+
+    /// Whether this is the last entry in the directory.
+    last: bool,
 }
 }
 
 
 impl TreeTrunk {
 impl TreeTrunk {
@@ -91,19 +103,19 @@ impl TreeTrunk {
     ///
     ///
     /// This takes a `&mut self` because the results of each file are stored
     /// This takes a `&mut self` because the results of each file are stored
     /// and used in future rows.
     /// and used in future rows.
-    pub fn new_row(&mut self, depth: usize, last: bool) -> &[TreePart] {
+    pub fn new_row(&mut self, params: TreeParams) -> &[TreePart] {
 
 
         // If this isn’t our first iteration, then update the tree parts thus
         // If this isn’t our first iteration, then update the tree parts thus
         // far to account for there being another row after it.
         // far to account for there being another row after it.
-        if let Some((last_depth, last_last)) = self.last_params {
-            self.stack[last_depth] = if last_last { TreePart::Blank } else { TreePart::Line };
+        if let Some(last) = self.last_params {
+            self.stack[last.depth] = if last.last { TreePart::Blank } else { TreePart::Line };
         }
         }
 
 
         // Make sure the stack has enough space, then add or modify another
         // Make sure the stack has enough space, then add or modify another
         // part into it.
         // part into it.
-        self.stack.resize(depth + 1, TreePart::Edge);
-        self.stack[depth] = if last { TreePart::Corner } else { TreePart::Edge };
-        self.last_params = Some((depth, last));
+        self.stack.resize(params.depth + 1, TreePart::Edge);
+        self.stack[params.depth] = if params.last { TreePart::Corner } else { TreePart::Edge };
+        self.last_params = Some(params);
 
 
         // Return the tree parts as a slice of the stack.
         // Return the tree parts as a slice of the stack.
         //
         //
@@ -123,6 +135,16 @@ impl TreeTrunk {
     }
     }
 }
 }
 
 
+impl TreeParams {
+    pub fn new(depth: usize, last: bool) -> TreeParams {
+        TreeParams { depth, last }
+    }
+
+    pub fn is_zero(&self) -> bool {
+        self.depth == 0
+    }
+}
+
 
 
 #[cfg(test)]
 #[cfg(test)]
 mod test {
 mod test {
@@ -131,47 +153,47 @@ mod test {
     #[test]
     #[test]
     fn empty_at_first() {
     fn empty_at_first() {
         let mut tt = TreeTrunk::default();
         let mut tt = TreeTrunk::default();
-        assert_eq!(tt.new_row(0, true), &[]);
+        assert_eq!(tt.new_row(TreeParams::new(0, true)), &[]);
     }
     }
 
 
     #[test]
     #[test]
     fn one_child() {
     fn one_child() {
         let mut tt = TreeTrunk::default();
         let mut tt = TreeTrunk::default();
-        assert_eq!(tt.new_row(0, true), &[]);
-        assert_eq!(tt.new_row(1, true), &[ TreePart::Corner ]);
+        assert_eq!(tt.new_row(TreeParams::new(0, true)), &[]);
+        assert_eq!(tt.new_row(TreeParams::new(1, true)), &[ TreePart::Corner ]);
     }
     }
 
 
     #[test]
     #[test]
     fn two_children() {
     fn two_children() {
         let mut tt = TreeTrunk::default();
         let mut tt = TreeTrunk::default();
-        assert_eq!(tt.new_row(0, true), &[]);
-        assert_eq!(tt.new_row(1, false), &[ TreePart::Edge ]);
-        assert_eq!(tt.new_row(1, true),  &[ TreePart::Corner ]);
+        assert_eq!(tt.new_row(TreeParams::new(0, true)), &[]);
+        assert_eq!(tt.new_row(TreeParams::new(1, false)), &[ TreePart::Edge ]);
+        assert_eq!(tt.new_row(TreeParams::new(1, true)),  &[ TreePart::Corner ]);
     }
     }
 
 
     #[test]
     #[test]
     fn two_times_two_children() {
     fn two_times_two_children() {
         let mut tt = TreeTrunk::default();
         let mut tt = TreeTrunk::default();
-        assert_eq!(tt.new_row(0, false), &[]);
-        assert_eq!(tt.new_row(1, false), &[ TreePart::Edge ]);
-        assert_eq!(tt.new_row(1, true),  &[ TreePart::Corner ]);
+        assert_eq!(tt.new_row(TreeParams::new(0, false)), &[]);
+        assert_eq!(tt.new_row(TreeParams::new(1, false)), &[ TreePart::Edge ]);
+        assert_eq!(tt.new_row(TreeParams::new(1, true)),  &[ TreePart::Corner ]);
 
 
-        assert_eq!(tt.new_row(0, true), &[]);
-        assert_eq!(tt.new_row(1, false), &[ TreePart::Edge ]);
-        assert_eq!(tt.new_row(1, true),  &[ TreePart::Corner ]);
+        assert_eq!(tt.new_row(TreeParams::new(0, true)), &[]);
+        assert_eq!(tt.new_row(TreeParams::new(1, false)), &[ TreePart::Edge ]);
+        assert_eq!(tt.new_row(TreeParams::new(1, true)),  &[ TreePart::Corner ]);
     }
     }
 
 
     #[test]
     #[test]
     fn two_times_two_nested_children() {
     fn two_times_two_nested_children() {
         let mut tt = TreeTrunk::default();
         let mut tt = TreeTrunk::default();
-        assert_eq!(tt.new_row(0, true), &[]);
+        assert_eq!(tt.new_row(TreeParams::new(0, true)), &[]);
 
 
-        assert_eq!(tt.new_row(1, false), &[ TreePart::Edge ]);
-        assert_eq!(tt.new_row(2, false), &[ TreePart::Line, TreePart::Edge ]);
-        assert_eq!(tt.new_row(2, true),  &[ TreePart::Line, TreePart::Corner ]);
+        assert_eq!(tt.new_row(TreeParams::new(1, false)), &[ TreePart::Edge ]);
+        assert_eq!(tt.new_row(TreeParams::new(2, false)), &[ TreePart::Line, TreePart::Edge ]);
+        assert_eq!(tt.new_row(TreeParams::new(2, true)),  &[ TreePart::Line, TreePart::Corner ]);
 
 
-        assert_eq!(tt.new_row(1, true),  &[ TreePart::Corner ]);
-        assert_eq!(tt.new_row(2, false), &[ TreePart::Blank, TreePart::Edge ]);
-        assert_eq!(tt.new_row(2, true),  &[ TreePart::Blank, TreePart::Corner ]);
+        assert_eq!(tt.new_row(TreeParams::new(1, true)),  &[ TreePart::Corner ]);
+        assert_eq!(tt.new_row(TreeParams::new(2, false)), &[ TreePart::Blank, TreePart::Edge ]);
+        assert_eq!(tt.new_row(TreeParams::new(2, true)),  &[ TreePart::Blank, TreePart::Corner ]);
     }
     }
 }
 }