mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-12-28 10:40:48 +00:00
Make struct for all tree parameters
The fields for ‘depth’ and ‘last’ were being passed around separately, but were always used together.
This commit is contained in:
parent
09b6ee7097
commit
8453f45f99
@ -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,
|
tree: TreeParams::new(depth, index == num_eggs - 1),
|
||||||
cells: egg.table_row,
|
cells: egg.table_row,
|
||||||
name: FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, self.colours).paint().promote(),
|
name: FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, self.colours).paint().promote(),
|
||||||
last: index == num_eggs - 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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 {
|
let name = TextCell::paint(self.colours.broken_arrow, error_message);
|
||||||
depth: depth,
|
Row { cells: None, name, tree }
|
||||||
cells: None,
|
|
||||||
name: TextCell::paint(self.colours.broken_arrow, error_message),
|
|
||||||
last: last,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_xattr(&self, xattr: Attribute, depth: usize, last: bool) -> Row {
|
fn render_xattr(&self, xattr: Attribute, tree: TreeParams) -> Row {
|
||||||
Row {
|
let name = TextCell::paint(self.colours.perms.attribute, format!("{} (len {})", xattr.name, xattr.size));
|
||||||
depth: depth,
|
Row { cells: None, name, tree }
|
||||||
cells: None,
|
|
||||||
name: TextCell::paint(self.colours.perms.attribute, format!("{} (len {})", xattr.name, xattr.size)),
|
|
||||||
last: last,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_file(&self, cells: TableRow, name_cell: TextCell, depth: usize, last: bool) -> Row {
|
pub fn render_file(&self, cells: TableRow, name: TextCell, tree: TreeParams) -> Row {
|
||||||
Row {
|
Row { cells: Some(cells), name, tree }
|
||||||
depth: depth,
|
|
||||||
cells: Some(cells),
|
|
||||||
name: name_cell,
|
|
||||||
last: last,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
/// Information used to determine which symbols to display in a tree.
|
||||||
/// on top have depth 0.
|
pub tree: TreeParams,
|
||||||
pub depth: usize,
|
|
||||||
|
|
||||||
/// Whether this is the last entry in the directory. This flag is used
|
|
||||||
/// when calculating the tree view.
|
|
||||||
pub last: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
if let Some(last) = self.last_params {
|
||||||
self.stack[last_depth] = if last_last { TreePart::Blank } else { TreePart::Line };
|
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.resize(params.depth + 1, TreePart::Edge);
|
||||||
self.stack[depth] = if last { TreePart::Corner } else { TreePart::Edge };
|
self.stack[params.depth] = if params.last { TreePart::Corner } else { TreePart::Edge };
|
||||||
self.last_params = Some((depth, last));
|
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(TreeParams::new(0, true)), &[]);
|
||||||
assert_eq!(tt.new_row(1, true), &[ TreePart::Corner ]);
|
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(TreeParams::new(0, true)), &[]);
|
||||||
assert_eq!(tt.new_row(1, false), &[ TreePart::Edge ]);
|
assert_eq!(tt.new_row(TreeParams::new(1, false)), &[ TreePart::Edge ]);
|
||||||
assert_eq!(tt.new_row(1, true), &[ TreePart::Corner ]);
|
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(TreeParams::new(0, false)), &[]);
|
||||||
assert_eq!(tt.new_row(1, false), &[ TreePart::Edge ]);
|
assert_eq!(tt.new_row(TreeParams::new(1, false)), &[ TreePart::Edge ]);
|
||||||
assert_eq!(tt.new_row(1, true), &[ TreePart::Corner ]);
|
assert_eq!(tt.new_row(TreeParams::new(1, true)), &[ TreePart::Corner ]);
|
||||||
|
|
||||||
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(TreeParams::new(1, false)), &[ TreePart::Edge ]);
|
||||||
assert_eq!(tt.new_row(1, true), &[ TreePart::Corner ]);
|
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(TreeParams::new(1, false)), &[ TreePart::Edge ]);
|
||||||
assert_eq!(tt.new_row(2, false), &[ TreePart::Line, TreePart::Edge ]);
|
assert_eq!(tt.new_row(TreeParams::new(2, false)), &[ TreePart::Line, TreePart::Edge ]);
|
||||||
assert_eq!(tt.new_row(2, true), &[ TreePart::Line, TreePart::Corner ]);
|
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(TreeParams::new(1, true)), &[ TreePart::Corner ]);
|
||||||
assert_eq!(tt.new_row(2, false), &[ TreePart::Blank, TreePart::Edge ]);
|
assert_eq!(tt.new_row(TreeParams::new(2, false)), &[ TreePart::Blank, TreePart::Edge ]);
|
||||||
assert_eq!(tt.new_row(2, true), &[ TreePart::Blank, TreePart::Corner ]);
|
assert_eq!(tt.new_row(TreeParams::new(2, true)), &[ TreePart::Blank, TreePart::Corner ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user