Move Colour and Classify to the View

All four view types — lines, grid, details, and grid-details — held their own colours and classify flags.

This didn’t make any sense for the grid-details view, which had to pick which one to use: the values were in there twice.

It also gave the Table in the details view access to more information than it really should have had.

Now, those two flags are returned separately from the view “mode”, which is the new term for one of those four things.
This commit is contained in:
Benjamin Sago 2017-06-24 22:39:15 +01:00
parent 763e833b6f
commit aea0035f94
16 changed files with 194 additions and 204 deletions

View File

@ -25,9 +25,9 @@ use std::path::{Component, Path};
use ansi_term::{ANSIStrings, Style}; use ansi_term::{ANSIStrings, Style};
use fs::{Dir, File}; use fs::{Dir, File};
use options::{Options, View}; use options::{Options, View, Mode};
pub use options::Misfire; pub use options::Misfire;
use output::escape; use output::{escape, lines};
mod fs; mod fs;
mod info; mod info;
@ -164,11 +164,12 @@ impl<'w, W: Write + 'w> Exa<'w, W> {
/// printing differently... /// printing differently...
fn print_files(&mut self, dir: Option<&Dir>, files: Vec<File>) -> IOResult<()> { fn print_files(&mut self, dir: Option<&Dir>, files: Vec<File>) -> IOResult<()> {
if !files.is_empty() { if !files.is_empty() {
match self.options.view { let View { ref mode, colours, classify } = self.options.view;
View::Grid(ref g) => g.view(&files, self.writer), match *mode {
View::Details(ref d) => d.view(dir, files, self.writer), Mode::Grid(ref g) => g.view(&files, self.writer, &colours, classify),
View::GridDetails(ref gd) => gd.view(dir, files, self.writer), Mode::Details(ref d) => d.view(dir, files, self.writer, &colours, classify),
View::Lines(ref l) => l.view(files, self.writer), Mode::GridDetails(ref gd) => gd.view(dir, files, self.writer, &colours, classify),
Mode::Lines => lines::view(files, self.writer, &colours, classify),
} }
} }
else { else {

View File

@ -18,7 +18,7 @@ mod misfire;
pub use self::misfire::Misfire; pub use self::misfire::Misfire;
mod view; mod view;
pub use self::view::View; pub use self::view::{View, Mode};
/// These **options** represent a parsed, error-checked versions of the /// These **options** represent a parsed, error-checked versions of the
@ -123,9 +123,9 @@ impl Options {
/// status column. Its only worth trying to discover a repository if the /// status column. Its only worth trying to discover a repository if the
/// results will end up being displayed. /// results will end up being displayed.
pub fn should_scan_for_git(&self) -> bool { pub fn should_scan_for_git(&self) -> bool {
match self.view { match self.view.mode {
View::Details(Details { columns: Some(cols), .. }) | Mode::Details(Details { columns: Some(cols), .. }) |
View::GridDetails(GridDetails { details: Details { columns: Some(cols), .. }, .. }) => cols.should_scan_for_git(), Mode::GridDetails(GridDetails { details: Details { columns: Some(cols), .. }, .. }) => cols.should_scan_for_git(),
_ => false, _ => false,
} }
} }

View File

@ -3,7 +3,7 @@ use std::env::var_os;
use getopts; use getopts;
use output::Colours; use output::Colours;
use output::{Grid, Details, GridDetails, Lines}; use output::{Grid, Details, GridDetails};
use output::column::{Columns, TimeTypes, SizeFormat}; use output::column::{Columns, TimeTypes, SizeFormat};
use output::file_name::Classify; use output::file_name::Classify;
use options::{FileFilter, DirAction, Misfire}; use options::{FileFilter, DirAction, Misfire};
@ -13,11 +13,19 @@ use fs::feature::xattr;
/// The **view** contains all information about how to format output. /// The **view** contains all information about how to format output.
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub enum View { pub struct View {
pub mode: Mode,
pub colours: Colours,
pub classify: Classify,
}
/// The **mode** is the “type” of output.
#[derive(PartialEq, Debug, Clone)]
pub enum Mode {
Details(Details), Details(Details),
Grid(Grid), Grid(Grid),
GridDetails(GridDetails), GridDetails(GridDetails),
Lines(Lines), Lines,
} }
impl View { impl View {
@ -58,11 +66,11 @@ impl View {
recurse: dir_action.recurse_options(), recurse: dir_action.recurse_options(),
filter: filter.clone(), filter: filter.clone(),
xattr: xattr::ENABLED && matches.opt_present("extended"), xattr: xattr::ENABLED && matches.opt_present("extended"),
colours: colours,
classify: Classify::deduce(matches),
}; };
Ok(details) let classify = Classify::deduce(matches);
Ok(View { mode: Mode::Details(details), colours, classify })
} }
}; };
@ -104,7 +112,7 @@ impl View {
Err(Useless("across", true, "oneline")) Err(Useless("across", true, "oneline"))
} }
else { else {
Ok(View::Lines(Lines { colours, classify })) Ok(View { mode: Mode::Lines, colours, classify })
} }
} }
else if matches.opt_present("tree") { else if matches.opt_present("tree") {
@ -114,21 +122,17 @@ impl View {
recurse: dir_action.recurse_options(), recurse: dir_action.recurse_options(),
filter: filter.clone(), // TODO: clone filter: filter.clone(), // TODO: clone
xattr: false, xattr: false,
colours: colours,
classify: classify,
}; };
Ok(View::Details(details)) Ok(View { mode: Mode::Details(details), colours, classify })
} }
else { else {
let grid = Grid { let grid = Grid {
across: matches.opt_present("across"), across: matches.opt_present("across"),
console_width: width, console_width: width,
colours: colours,
classify: classify,
}; };
Ok(View::Grid(grid)) Ok(View { mode: Mode::Grid(grid), colours, classify })
} }
} }
else { else {
@ -148,30 +152,32 @@ impl View {
recurse: dir_action.recurse_options(), recurse: dir_action.recurse_options(),
filter: filter.clone(), filter: filter.clone(),
xattr: false, xattr: false,
colours: colours,
classify: classify,
}; };
Ok(View::Details(details)) Ok(View { mode: Mode::Details(details), colours, classify })
} }
else { else {
Ok(View::Lines(Lines { colours, classify })) Ok(View { mode: Mode::Lines, colours, classify })
} }
} }
}; };
if matches.opt_present("long") { if matches.opt_present("long") {
let details = long()?; let view = long()?;
if matches.opt_present("grid") { if matches.opt_present("grid") {
match other_options_scan() { if let View { colours: _, classify: _, mode: Mode::Details(details) } = view {
Ok(View::Grid(grid)) => return Ok(View::GridDetails(GridDetails { grid, details })), let others = other_options_scan()?;
Ok(lines) => return Ok(lines), match others.mode {
Err(e) => return Err(e), Mode::Grid(grid) => return Ok(View { mode: Mode::GridDetails(GridDetails { grid: grid, details: details }), colours: others.colours, classify: others.classify }),
}; _ => return Ok(others),
};
}
else {
unreachable!()
}
} }
else { else {
return Ok(View::Details(details)); return Ok(view);
} }
} }

View File

@ -133,13 +133,6 @@ pub struct Details {
/// Whether to show each file's extended attributes. /// Whether to show each file's extended attributes.
pub xattr: bool, pub xattr: bool,
/// The colours to use to display information in the table, including the
/// colour of the tree view symbols.
pub colours: Colours,
/// Whether to show a file type indiccator.
pub classify: Classify,
} }
/// The **environment** struct contains any data that could change between /// The **environment** struct contains any data that could change between
@ -228,7 +221,7 @@ impl Details {
/// Print the details of the given vector of files -- all of which will /// Print the details of the given vector of files -- all of which will
/// have been read from the given directory, if present -- to stdout. /// have been read from the given directory, if present -- to stdout.
pub fn view<W: Write>(&self, dir: Option<&Dir>, files: Vec<File>, w: &mut W) -> IOResult<()> { pub fn view<W: Write>(&self, dir: Option<&Dir>, files: Vec<File>, w: &mut W, colours: &Colours, classify: Classify) -> IOResult<()> {
// First, transform the Columns object into a vector of columns for // First, transform the Columns object into a vector of columns for
// the current directory. // the current directory.
@ -243,7 +236,9 @@ impl Details {
// Build the table to put rows in. // Build the table to put rows in.
let mut table = Table { let mut table = Table {
columns: &*columns_for_dir, columns: &*columns_for_dir,
opts: self, colours: colours,
classify: classify,
xattr: self.xattr,
env: env, env: env,
rows: Vec::new(), rows: Vec::new(),
}; };
@ -306,7 +301,7 @@ impl Details {
let cells = table.cells_for_file(&file, !xattrs.is_empty()); let cells = table.cells_for_file(&file, !xattrs.is_empty());
if !table.opts.xattr { if !table.xattr {
xattrs.clear(); xattrs.clear();
} }
@ -336,7 +331,7 @@ impl Details {
let row = Row { let row = Row {
depth: depth, depth: depth,
cells: Some(egg.cells), cells: Some(egg.cells),
name: FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, &self.colours).paint().promote(), name: FileName::new(&egg.file, LinkStyle::FullLinkPaths, table.classify, table.colours).paint().promote(),
last: index == num_eggs - 1, last: index == num_eggs - 1,
}; };
@ -420,9 +415,10 @@ impl Row {
/// directories. /// directories.
pub struct Table<'a, U: 'a> { // where U: Users+Groups pub struct Table<'a, U: 'a> { // where U: Users+Groups
pub rows: Vec<Row>, pub rows: Vec<Row>,
pub columns: &'a [Column], pub columns: &'a [Column],
pub opts: &'a Details, pub colours: &'a Colours,
pub xattr: bool,
pub classify: Classify,
pub env: Arc<Environment<U>>, pub env: Arc<Environment<U>>,
} }
@ -434,8 +430,8 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
pub fn add_header(&mut self) { pub fn add_header(&mut self) {
let row = Row { let row = Row {
depth: 0, depth: 0,
cells: Some(self.columns.iter().map(|c| TextCell::paint_str(self.opts.colours.header, c.header())).collect()), cells: Some(self.columns.iter().map(|c| TextCell::paint_str(self.colours.header, c.header())).collect()),
name: TextCell::paint_str(self.opts.colours.header, "Name"), name: TextCell::paint_str(self.colours.header, "Name"),
last: false, last: false,
}; };
@ -451,7 +447,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
let row = Row { let row = Row {
depth: depth, depth: depth,
cells: None, cells: None,
name: TextCell::paint(self.opts.colours.broken_arrow, error_message), name: TextCell::paint(self.colours.broken_arrow, error_message),
last: last, last: last,
}; };
@ -462,7 +458,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
let row = Row { let row = Row {
depth: depth, depth: depth,
cells: None, cells: None,
name: TextCell::paint(self.opts.colours.perms.attribute, format!("{} (len {})", xattr.name, xattr.size)), name: TextCell::paint(self.colours.perms.attribute, format!("{} (len {})", xattr.name, xattr.size)),
last: last, last: last,
}; };
@ -470,7 +466,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
} }
pub fn filename(&self, file: File, links: LinkStyle) -> TextCellContents { pub fn filename(&self, file: File, links: LinkStyle) -> TextCellContents {
FileName::new(&file, links, self.opts.classify, &self.opts.colours).paint() FileName::new(&file, links, self.classify, &self.colours).paint()
} }
pub fn add_file_with_cells(&mut self, cells: Vec<TextCell>, name_cell: TextCell, depth: usize, last: bool) { pub fn add_file_with_cells(&mut self, cells: Vec<TextCell>, name_cell: TextCell, depth: usize, last: bool) {
@ -504,17 +500,17 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
use output::column::TimeType::*; use output::column::TimeType::*;
match *column { match *column {
Column::Permissions => self.permissions_plus(file, xattrs).render(&self.opts.colours), Column::Permissions => self.permissions_plus(file, xattrs).render(&self.colours),
Column::FileSize(fmt) => file.size().render(&self.opts.colours, fmt, &self.env.numeric), Column::FileSize(fmt) => file.size().render(&self.colours, fmt, &self.env.numeric),
Column::Timestamp(Modified) => file.modified_time().render(&self.opts.colours, &self.env.tz, &self.env.date_and_time, &self.env.date_and_year, &self.env.time, self.env.current_year), Column::Timestamp(Modified) => file.modified_time().render(&self.colours, &self.env.tz, &self.env.date_and_time, &self.env.date_and_year, &self.env.time, self.env.current_year),
Column::Timestamp(Created) => file.created_time().render( &self.opts.colours, &self.env.tz, &self.env.date_and_time, &self.env.date_and_year, &self.env.time, self.env.current_year), Column::Timestamp(Created) => file.created_time().render( &self.colours, &self.env.tz, &self.env.date_and_time, &self.env.date_and_year, &self.env.time, self.env.current_year),
Column::Timestamp(Accessed) => file.accessed_time().render(&self.opts.colours, &self.env.tz, &self.env.date_and_time, &self.env.date_and_year, &self.env.time, self.env.current_year), Column::Timestamp(Accessed) => file.accessed_time().render(&self.colours, &self.env.tz, &self.env.date_and_time, &self.env.date_and_year, &self.env.time, self.env.current_year),
Column::HardLinks => file.links().render(&self.opts.colours, &self.env.numeric), Column::HardLinks => file.links().render(&self.colours, &self.env.numeric),
Column::Inode => file.inode().render(&self.opts.colours), Column::Inode => file.inode().render(&self.colours),
Column::Blocks => file.blocks().render(&self.opts.colours), Column::Blocks => file.blocks().render(&self.colours),
Column::User => file.user().render(&self.opts.colours, &*self.env.lock_users()), Column::User => file.user().render(&self.colours, &*self.env.lock_users()),
Column::Group => file.group().render(&self.opts.colours, &*self.env.lock_users()), Column::Group => file.group().render(&self.colours, &*self.env.lock_users()),
Column::GitStatus => file.git_status().render(&self.opts.colours), Column::GitStatus => file.git_status().render(&self.colours),
} }
} }
@ -554,7 +550,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
let mut filename = TextCell::default(); let mut filename = TextCell::default();
for tree_part in tree_trunk.new_row(row.depth, row.last) { for tree_part in tree_trunk.new_row(row.depth, row.last) {
filename.push(self.opts.colours.punctuation.paint(tree_part.ascii_art()), 4); filename.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

View File

@ -11,12 +11,10 @@ use output::file_name::{FileName, LinkStyle, Classify};
pub struct Grid { pub struct Grid {
pub across: bool, pub across: bool,
pub console_width: usize, pub console_width: usize,
pub colours: Colours,
pub classify: Classify,
} }
impl Grid { impl Grid {
pub fn view<W: Write>(&self, files: &[File], w: &mut W) -> IOResult<()> { pub fn view<W: Write>(&self, files: &[File], w: &mut W, colours: &Colours, classify: Classify) -> IOResult<()> {
let direction = if self.across { grid::Direction::LeftToRight } let direction = if self.across { grid::Direction::LeftToRight }
else { grid::Direction::TopToBottom }; else { grid::Direction::TopToBottom };
@ -28,7 +26,7 @@ impl Grid {
grid.reserve(files.len()); grid.reserve(files.len());
for file in files.iter() { for file in files.iter() {
let filename = FileName::new(file, LinkStyle::JustFilenames, self.classify, &self.colours).paint(); let filename = FileName::new(file, LinkStyle::JustFilenames, classify, colours).paint();
let width = filename.width(); let width = filename.width();
grid.add(grid::Cell { grid.add(grid::Cell {
@ -43,7 +41,7 @@ impl Grid {
else { else {
// File names too long for a grid - drop down to just listing them! // File names too long for a grid - drop down to just listing them!
for file in files.iter() { for file in files.iter() {
let name_cell = FileName::new(file, LinkStyle::JustFilenames, self.classify, &self.colours).paint(); let name_cell = FileName::new(file, LinkStyle::JustFilenames, classify, colours).paint();
writeln!(w, "{}", name_cell.strings())?; writeln!(w, "{}", name_cell.strings())?;
} }
Ok(()) Ok(())

View File

@ -10,9 +10,10 @@ use fs::feature::xattr::FileAttributes;
use output::cell::TextCell; use output::cell::TextCell;
use output::column::Column; use output::column::Column;
use output::colours::Colours;
use output::details::{Details, Table, Environment}; use output::details::{Details, Table, Environment};
use output::grid::Grid; use output::grid::Grid;
use output::file_name::LinkStyle; use output::file_name::{Classify, LinkStyle};
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
@ -29,7 +30,7 @@ fn file_has_xattrs(file: &File) -> bool {
} }
impl GridDetails { impl GridDetails {
pub fn view<W>(&self, dir: Option<&Dir>, files: Vec<File>, w: &mut W) -> IOResult<()> pub fn view<W>(&self, dir: Option<&Dir>, files: Vec<File>, w: &mut W, colours: &Colours, classify: Classify) -> IOResult<()>
where W: Write { where W: Write {
let columns_for_dir = match self.details.columns { let columns_for_dir = match self.details.columns {
Some(cols) => cols.for_dir(dir), Some(cols) => cols.for_dir(dir),
@ -40,7 +41,7 @@ impl GridDetails {
let (cells, file_names) = { let (cells, file_names) = {
let first_table = self.make_table(env.clone(), &*columns_for_dir); let first_table = self.make_table(env.clone(), &*columns_for_dir, colours, classify);
let cells = files.iter() let cells = files.iter()
.map(|file| first_table.cells_for_file(file, file_has_xattrs(file))) .map(|file| first_table.cells_for_file(file, file_has_xattrs(file)))
@ -53,10 +54,10 @@ impl GridDetails {
(cells, file_names) (cells, file_names)
}; };
let mut last_working_table = self.make_grid(env.clone(), 1, &columns_for_dir, &file_names, cells.clone()); let mut last_working_table = self.make_grid(env.clone(), 1, &columns_for_dir, &file_names, cells.clone(), colours, classify);
for column_count in 2.. { for column_count in 2.. {
let grid = self.make_grid(env.clone(), column_count, &columns_for_dir, &file_names, cells.clone()); let grid = self.make_grid(env.clone(), column_count, &columns_for_dir, &file_names, cells.clone(), colours, classify);
let the_grid_fits = { let the_grid_fits = {
let d = grid.fit_into_columns(column_count); let d = grid.fit_into_columns(column_count);
@ -74,12 +75,11 @@ impl GridDetails {
Ok(()) Ok(())
} }
fn make_table<'a>(&'a self, env: Arc<Environment<UsersCache>>, columns_for_dir: &'a [Column]) -> Table<UsersCache> { fn make_table<'a>(&'a self, env: Arc<Environment<UsersCache>>, columns_for_dir: &'a [Column], colours: &'a Colours, classify: Classify) -> Table<UsersCache> {
let mut table = Table { let mut table = Table {
columns: columns_for_dir, columns: columns_for_dir,
opts: &self.details, colours, classify, env,
env: env, xattr: self.details.xattr,
rows: Vec::new(), rows: Vec::new(),
}; };
@ -87,10 +87,10 @@ impl GridDetails {
table table
} }
fn make_grid<'a>(&'a self, env: Arc<Environment<UsersCache>>, column_count: usize, columns_for_dir: &'a [Column], file_names: &[TextCell], cells: Vec<Vec<TextCell>>) -> grid::Grid { fn make_grid<'a>(&'a self, env: Arc<Environment<UsersCache>>, column_count: usize, columns_for_dir: &'a [Column], file_names: &[TextCell], cells: Vec<Vec<TextCell>>, colours: &'a Colours, classify: Classify) -> grid::Grid {
let mut tables = Vec::new(); let mut tables = Vec::new();
for _ in 0 .. column_count { for _ in 0 .. column_count {
tables.push(self.make_table(env.clone(), columns_for_dir)); tables.push(self.make_table(env.clone(), columns_for_dir, colours, classify));
} }
let mut num_cells = cells.len(); let mut num_cells = cells.len();

View File

@ -8,19 +8,11 @@ use output::file_name::{FileName, LinkStyle, Classify};
use super::colours::Colours; use super::colours::Colours;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Lines {
pub colours: Colours,
pub classify: Classify,
}
/// The lines view literally just displays each file, line-by-line. /// The lines view literally just displays each file, line-by-line.
impl Lines { pub fn view<W: Write>(files: Vec<File>, w: &mut W, colours: &Colours, classify: Classify) -> IOResult<()> {
pub fn view<W: Write>(&self, files: Vec<File>, w: &mut W) -> IOResult<()> { for file in files {
for file in files { let name_cell = FileName::new(&file, LinkStyle::FullLinkPaths, classify, colours).paint();
let name_cell = FileName::new(&file, LinkStyle::FullLinkPaths, self.classify, &self.colours).paint(); writeln!(w, "{}", ANSIStrings(&name_cell))?;
writeln!(w, "{}", ANSIStrings(&name_cell))?;
}
Ok(())
} }
Ok(())
} }

View File

@ -3,12 +3,11 @@ pub use self::colours::Colours;
pub use self::details::Details; pub use self::details::Details;
pub use self::grid_details::GridDetails; pub use self::grid_details::GridDetails;
pub use self::grid::Grid; pub use self::grid::Grid;
pub use self::lines::Lines;
pub use self::escape::escape; pub use self::escape::escape;
mod grid; mod grid;
pub mod details; pub mod details;
mod lines; pub mod lines;
mod grid_details; mod grid_details;
pub mod column; pub mod column;
mod cell; mod cell;

View File

@ -15,7 +15,7 @@ impl f::Blocks {
#[cfg(test)] #[cfg(test)]
pub mod test { pub mod test {
use output::details::Details; use output::colours::Colours;
use output::cell::TextCell; use output::cell::TextCell;
use fs::fields as f; use fs::fields as f;
@ -24,21 +24,21 @@ pub mod test {
#[test] #[test]
fn blocklessness() { fn blocklessness() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.punctuation = Green.italic(); colours.punctuation = Green.italic();
let blox = f::Blocks::None; let blox = f::Blocks::None;
let expected = TextCell::blank(Green.italic()); let expected = TextCell::blank(Green.italic());
assert_eq!(expected, blox.render(&details.colours).into()); assert_eq!(expected, blox.render(&colours).into());
} }
#[test] #[test]
fn blockfulity() { fn blockfulity() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.blocks = Red.blink(); colours.blocks = Red.blink();
let blox = f::Blocks::Some(3005); let blox = f::Blocks::Some(3005);
let expected = TextCell::paint_str(Red.blink(), "3005"); let expected = TextCell::paint_str(Red.blink(), "3005");
assert_eq!(expected, blox.render(&details.colours).into()); assert_eq!(expected, blox.render(&colours).into());
} }
} }

View File

@ -33,7 +33,7 @@ impl f::GitStatus {
#[cfg(test)] #[cfg(test)]
pub mod test { pub mod test {
use output::details::Details; use output::colours::Colours;
use output::cell::{TextCell, DisplayWidth}; use output::cell::{TextCell, DisplayWidth};
use fs::fields as f; use fs::fields as f;
@ -42,8 +42,8 @@ pub mod test {
#[test] #[test]
fn git_blank() { fn git_blank() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.punctuation = Fixed(44).normal(); colours.punctuation = Fixed(44).normal();
let stati = f::Git { let stati = f::Git {
staged: f::GitStatus::NotModified, staged: f::GitStatus::NotModified,
@ -58,15 +58,15 @@ pub mod test {
].into(), ].into(),
}; };
assert_eq!(expected, stati.render(&details.colours).into()) assert_eq!(expected, stati.render(&colours).into())
} }
#[test] #[test]
fn git_new_changed() { fn git_new_changed() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.git.new = Red.normal(); colours.git.new = Red.normal();
details.colours.git.modified = Purple.normal(); colours.git.modified = Purple.normal();
let stati = f::Git { let stati = f::Git {
staged: f::GitStatus::New, staged: f::GitStatus::New,
@ -81,6 +81,6 @@ pub mod test {
].into(), ].into(),
}; };
assert_eq!(expected, stati.render(&details.colours).into()) assert_eq!(expected, stati.render(&colours).into())
} }
} }

View File

@ -32,10 +32,9 @@ impl f::Group {
#[cfg(test)] #[cfg(test)]
#[allow(unused_results)] #[allow(unused_results)]
pub mod test { pub mod test {
use output::details::Details;
use fs::fields as f; use fs::fields as f;
use output::cell::TextCell; use output::cell::TextCell;
use output::colours::Colours;
use users::{User, Group}; use users::{User, Group};
use users::mock::MockUsers; use users::mock::MockUsers;
@ -45,33 +44,33 @@ pub mod test {
#[test] #[test]
fn named() { fn named() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.group_not_yours = Fixed(101).normal(); colours.users.group_not_yours = Fixed(101).normal();
let mut users = MockUsers::with_current_uid(1000); let mut users = MockUsers::with_current_uid(1000);
users.add_group(Group::new(100, "folk")); users.add_group(Group::new(100, "folk"));
let group = f::Group(100); let group = f::Group(100);
let expected = TextCell::paint_str(Fixed(101).normal(), "folk"); let expected = TextCell::paint_str(Fixed(101).normal(), "folk");
assert_eq!(expected, group.render(&details.colours, &users)) assert_eq!(expected, group.render(&colours, &users))
} }
#[test] #[test]
fn unnamed() { fn unnamed() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.group_not_yours = Fixed(87).normal(); colours.users.group_not_yours = Fixed(87).normal();
let users = MockUsers::with_current_uid(1000); let users = MockUsers::with_current_uid(1000);
let group = f::Group(100); let group = f::Group(100);
let expected = TextCell::paint_str(Fixed(87).normal(), "100"); let expected = TextCell::paint_str(Fixed(87).normal(), "100");
assert_eq!(expected, group.render(&details.colours, &users)); assert_eq!(expected, group.render(&colours, &users));
} }
#[test] #[test]
fn primary() { fn primary() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.group_yours = Fixed(64).normal(); colours.users.group_yours = Fixed(64).normal();
let mut users = MockUsers::with_current_uid(2); let mut users = MockUsers::with_current_uid(2);
users.add_user(User::new(2, "eve", 100)); users.add_user(User::new(2, "eve", 100));
@ -79,13 +78,13 @@ pub mod test {
let group = f::Group(100); let group = f::Group(100);
let expected = TextCell::paint_str(Fixed(64).normal(), "folk"); let expected = TextCell::paint_str(Fixed(64).normal(), "folk");
assert_eq!(expected, group.render(&details.colours, &users)) assert_eq!(expected, group.render(&colours, &users))
} }
#[test] #[test]
fn secondary() { fn secondary() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.group_yours = Fixed(31).normal(); colours.users.group_yours = Fixed(31).normal();
let mut users = MockUsers::with_current_uid(2); let mut users = MockUsers::with_current_uid(2);
users.add_user(User::new(2, "eve", 666)); users.add_user(User::new(2, "eve", 666));
@ -95,16 +94,16 @@ pub mod test {
let group = f::Group(100); let group = f::Group(100);
let expected = TextCell::paint_str(Fixed(31).normal(), "folk"); let expected = TextCell::paint_str(Fixed(31).normal(), "folk");
assert_eq!(expected, group.render(&details.colours, &users)) assert_eq!(expected, group.render(&colours, &users))
} }
#[test] #[test]
fn overflow() { fn overflow() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.group_not_yours = Blue.underline(); colours.users.group_not_yours = Blue.underline();
let group = f::Group(2_147_483_648); let group = f::Group(2_147_483_648);
let expected = TextCell::paint_str(Blue.underline(), "2147483648"); let expected = TextCell::paint_str(Blue.underline(), "2147483648");
assert_eq!(expected, group.render(&details.colours, &MockUsers::with_current_uid(0))); assert_eq!(expected, group.render(&colours, &MockUsers::with_current_uid(0)));
} }
} }

View File

@ -12,7 +12,7 @@ impl f::Inode {
#[cfg(test)] #[cfg(test)]
pub mod test { pub mod test {
use output::details::Details; use output::colours::Colours;
use output::cell::TextCell; use output::cell::TextCell;
use fs::fields as f; use fs::fields as f;
@ -21,11 +21,11 @@ pub mod test {
#[test] #[test]
fn blocklessness() { fn blocklessness() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.inode = Cyan.underline(); colours.inode = Cyan.underline();
let io = f::Inode(1414213); let io = f::Inode(1414213);
let expected = TextCell::paint_str(Cyan.underline(), "1414213"); let expected = TextCell::paint_str(Cyan.underline(), "1414213");
assert_eq!(expected, io.render(&details.colours).into()); assert_eq!(expected, io.render(&colours).into());
} }
} }

View File

@ -17,7 +17,7 @@ impl f::Links {
#[cfg(test)] #[cfg(test)]
pub mod test { pub mod test {
use output::details::Details; use output::colours::Colours;
use output::cell::{TextCell, DisplayWidth}; use output::cell::{TextCell, DisplayWidth};
use fs::fields as f; use fs::fields as f;
@ -27,8 +27,8 @@ pub mod test {
#[test] #[test]
fn regular_file() { fn regular_file() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.links.normal = Blue.normal(); colours.links.normal = Blue.normal();
let stati = f::Links { let stati = f::Links {
count: 1, count: 1,
@ -40,13 +40,13 @@ pub mod test {
contents: vec![ Blue.paint("1") ].into(), contents: vec![ Blue.paint("1") ].into(),
}; };
assert_eq!(expected, stati.render(&details.colours, &locale::Numeric::english()).into()); assert_eq!(expected, stati.render(&colours, &locale::Numeric::english()).into());
} }
#[test] #[test]
fn regular_directory() { fn regular_directory() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.links.normal = Blue.normal(); colours.links.normal = Blue.normal();
let stati = f::Links { let stati = f::Links {
count: 3005, count: 3005,
@ -58,13 +58,13 @@ pub mod test {
contents: vec![ Blue.paint("3,005") ].into(), contents: vec![ Blue.paint("3,005") ].into(),
}; };
assert_eq!(expected, stati.render(&details.colours, &locale::Numeric::english()).into()); assert_eq!(expected, stati.render(&colours, &locale::Numeric::english()).into());
} }
#[test] #[test]
fn popular_file() { fn popular_file() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.links.multi_link_file = Blue.on(Red); colours.links.multi_link_file = Blue.on(Red);
let stati = f::Links { let stati = f::Links {
count: 3005, count: 3005,
@ -76,6 +76,6 @@ pub mod test {
contents: vec![ Blue.on(Red).paint("3,005") ].into(), contents: vec![ Blue.on(Red).paint("3,005") ].into(),
}; };
assert_eq!(expected, stati.render(&details.colours, &locale::Numeric::english()).into()); assert_eq!(expected, stati.render(&colours, &locale::Numeric::english()).into());
} }
} }

View File

@ -92,7 +92,7 @@ impl f::Type {
#[cfg(test)] #[cfg(test)]
#[allow(unused_results)] #[allow(unused_results)]
pub mod test { pub mod test {
use output::details::Details; use output::colours::Colours;
use output::cell::TextCellContents; use output::cell::TextCellContents;
use fs::fields as f; use fs::fields as f;
@ -101,8 +101,8 @@ pub mod test {
#[test] #[test]
fn negate() { fn negate() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.punctuation = Fixed(11).normal(); colours.punctuation = Fixed(11).normal();
let bits = f::Permissions { let bits = f::Permissions {
user_read: false, user_write: false, user_execute: false, setuid: false, user_read: false, user_write: false, user_execute: false, setuid: false,
@ -116,24 +116,24 @@ pub mod test {
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(11).paint("-"),
]); ]);
assert_eq!(expected, bits.render(&details.colours, false).into()) assert_eq!(expected, bits.render(&colours, false).into())
} }
#[test] #[test]
fn affirm() { fn affirm() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.perms.user_read = Fixed(101).normal(); colours.perms.user_read = Fixed(101).normal();
details.colours.perms.user_write = Fixed(102).normal(); colours.perms.user_write = Fixed(102).normal();
details.colours.perms.user_execute_file = Fixed(103).normal(); colours.perms.user_execute_file = Fixed(103).normal();
details.colours.perms.group_read = Fixed(104).normal(); colours.perms.group_read = Fixed(104).normal();
details.colours.perms.group_write = Fixed(105).normal(); colours.perms.group_write = Fixed(105).normal();
details.colours.perms.group_execute = Fixed(106).normal(); colours.perms.group_execute = Fixed(106).normal();
details.colours.perms.other_read = Fixed(107).normal(); colours.perms.other_read = Fixed(107).normal();
details.colours.perms.other_write = Fixed(108).normal(); colours.perms.other_write = Fixed(108).normal();
details.colours.perms.other_execute = Fixed(109).normal(); colours.perms.other_execute = Fixed(109).normal();
let bits = f::Permissions { let bits = f::Permissions {
user_read: true, user_write: true, user_execute: true, setuid: false, user_read: true, user_write: true, user_execute: true, setuid: false,
@ -147,16 +147,16 @@ pub mod test {
Fixed(107).paint("r"), Fixed(108).paint("w"), Fixed(109).paint("x"), Fixed(107).paint("r"), Fixed(108).paint("w"), Fixed(109).paint("x"),
]); ]);
assert_eq!(expected, bits.render(&details.colours, true).into()) assert_eq!(expected, bits.render(&colours, true).into())
} }
#[test] #[test]
fn specials() { fn specials() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.punctuation = Fixed(11).normal(); colours.punctuation = Fixed(11).normal();
details.colours.perms.special_user_file = Fixed(77).normal(); colours.perms.special_user_file = Fixed(77).normal();
details.colours.perms.special_other = Fixed(88).normal(); colours.perms.special_other = Fixed(88).normal();
let bits = f::Permissions { let bits = f::Permissions {
user_read: false, user_write: false, user_execute: true, setuid: true, user_read: false, user_write: false, user_execute: true, setuid: true,
@ -170,15 +170,15 @@ pub mod test {
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("t"), Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("t"),
]); ]);
assert_eq!(expected, bits.render(&details.colours, true).into()) assert_eq!(expected, bits.render(&colours, true).into())
} }
#[test] #[test]
fn extra_specials() { fn extra_specials() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.punctuation = Fixed(11).normal(); colours.punctuation = Fixed(11).normal();
details.colours.perms.special_other = Fixed(88).normal(); colours.perms.special_other = Fixed(88).normal();
let bits = f::Permissions { let bits = f::Permissions {
user_read: false, user_write: false, user_execute: false, setuid: true, user_read: false, user_write: false, user_execute: false, setuid: true,
@ -192,6 +192,6 @@ pub mod test {
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("T"), Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("T"),
]); ]);
assert_eq!(expected, bits.render(&details.colours, true).into()) assert_eq!(expected, bits.render(&colours, true).into())
} }
} }

View File

@ -67,7 +67,7 @@ impl f::DeviceIDs {
#[cfg(test)] #[cfg(test)]
pub mod test { pub mod test {
use output::details::Details; use output::colours::Colours;
use output::column::SizeFormat; use output::column::SizeFormat;
use output::cell::{TextCell, DisplayWidth}; use output::cell::{TextCell, DisplayWidth};
use fs::fields as f; use fs::fields as f;
@ -78,20 +78,20 @@ pub mod test {
#[test] #[test]
fn directory() { fn directory() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.punctuation = Green.italic(); colours.punctuation = Green.italic();
let directory = f::Size::None; let directory = f::Size::None;
let expected = TextCell::blank(Green.italic()); let expected = TextCell::blank(Green.italic());
assert_eq!(expected, directory.render(&details.colours, SizeFormat::JustBytes, &locale::Numeric::english())) assert_eq!(expected, directory.render(&colours, SizeFormat::JustBytes, &locale::Numeric::english()))
} }
#[test] #[test]
fn file_decimal() { fn file_decimal() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.size.numbers = Blue.on(Red); colours.size.numbers = Blue.on(Red);
details.colours.size.unit = Yellow.bold(); colours.size.unit = Yellow.bold();
let directory = f::Size::Some(2_100_000); let directory = f::Size::Some(2_100_000);
let expected = TextCell { let expected = TextCell {
@ -102,15 +102,15 @@ pub mod test {
].into(), ].into(),
}; };
assert_eq!(expected, directory.render(&details.colours, SizeFormat::DecimalBytes, &locale::Numeric::english())) assert_eq!(expected, directory.render(&colours, SizeFormat::DecimalBytes, &locale::Numeric::english()))
} }
#[test] #[test]
fn file_binary() { fn file_binary() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.size.numbers = Blue.on(Red); colours.size.numbers = Blue.on(Red);
details.colours.size.unit = Yellow.bold(); colours.size.unit = Yellow.bold();
let directory = f::Size::Some(1_048_576); let directory = f::Size::Some(1_048_576);
let expected = TextCell { let expected = TextCell {
@ -121,14 +121,14 @@ pub mod test {
].into(), ].into(),
}; };
assert_eq!(expected, directory.render(&details.colours, SizeFormat::BinaryBytes, &locale::Numeric::english())) assert_eq!(expected, directory.render(&colours, SizeFormat::BinaryBytes, &locale::Numeric::english()))
} }
#[test] #[test]
fn file_bytes() { fn file_bytes() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.size.numbers = Blue.on(Red); colours.size.numbers = Blue.on(Red);
let directory = f::Size::Some(1048576); let directory = f::Size::Some(1048576);
let expected = TextCell { let expected = TextCell {
@ -138,16 +138,16 @@ pub mod test {
].into(), ].into(),
}; };
assert_eq!(expected, directory.render(&details.colours, SizeFormat::JustBytes, &locale::Numeric::english())) assert_eq!(expected, directory.render(&colours, SizeFormat::JustBytes, &locale::Numeric::english()))
} }
#[test] #[test]
fn device_ids() { fn device_ids() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.size.major = Blue.on(Red); colours.size.major = Blue.on(Red);
details.colours.punctuation = Green.italic(); colours.punctuation = Green.italic();
details.colours.size.minor = Cyan.on(Yellow); colours.size.minor = Cyan.on(Yellow);
let directory = f::Size::DeviceIDs(f::DeviceIDs { major: 10, minor: 80 }); let directory = f::Size::DeviceIDs(f::DeviceIDs { major: 10, minor: 80 });
let expected = TextCell { let expected = TextCell {
@ -159,6 +159,6 @@ pub mod test {
].into(), ].into(),
}; };
assert_eq!(expected, directory.render(&details.colours, SizeFormat::JustBytes, &locale::Numeric::english())) assert_eq!(expected, directory.render(&colours, SizeFormat::JustBytes, &locale::Numeric::english()))
} }
} }

View File

@ -21,10 +21,9 @@ impl f::User {
#[cfg(test)] #[cfg(test)]
#[allow(unused_results)] #[allow(unused_results)]
pub mod test { pub mod test {
use output::details::Details;
use fs::fields as f; use fs::fields as f;
use output::cell::TextCell; use output::cell::TextCell;
use output::colours::Colours;
use users::User; use users::User;
use users::mock::MockUsers; use users::mock::MockUsers;
@ -32,59 +31,59 @@ pub mod test {
#[test] #[test]
fn named() { fn named() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.user_you = Red.bold(); colours.users.user_you = Red.bold();
let mut users = MockUsers::with_current_uid(1000); let mut users = MockUsers::with_current_uid(1000);
users.add_user(User::new(1000, "enoch", 100)); users.add_user(User::new(1000, "enoch", 100));
let user = f::User(1000); let user = f::User(1000);
let expected = TextCell::paint_str(Red.bold(), "enoch"); let expected = TextCell::paint_str(Red.bold(), "enoch");
assert_eq!(expected, user.render(&details.colours, &users)) assert_eq!(expected, user.render(&colours, &users))
} }
#[test] #[test]
fn unnamed() { fn unnamed() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.user_you = Cyan.bold(); colours.users.user_you = Cyan.bold();
let users = MockUsers::with_current_uid(1000); let users = MockUsers::with_current_uid(1000);
let user = f::User(1000); let user = f::User(1000);
let expected = TextCell::paint_str(Cyan.bold(), "1000"); let expected = TextCell::paint_str(Cyan.bold(), "1000");
assert_eq!(expected, user.render(&details.colours, &users)); assert_eq!(expected, user.render(&colours, &users));
} }
#[test] #[test]
fn different_named() { fn different_named() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.user_someone_else = Green.bold(); colours.users.user_someone_else = Green.bold();
let mut users = MockUsers::with_current_uid(0); let mut users = MockUsers::with_current_uid(0);
users.add_user(User::new(1000, "enoch", 100)); users.add_user(User::new(1000, "enoch", 100));
let user = f::User(1000); let user = f::User(1000);
let expected = TextCell::paint_str(Green.bold(), "enoch"); let expected = TextCell::paint_str(Green.bold(), "enoch");
assert_eq!(expected, user.render(&details.colours, &users)); assert_eq!(expected, user.render(&colours, &users));
} }
#[test] #[test]
fn different_unnamed() { fn different_unnamed() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.user_someone_else = Red.normal(); colours.users.user_someone_else = Red.normal();
let user = f::User(1000); let user = f::User(1000);
let expected = TextCell::paint_str(Red.normal(), "1000"); let expected = TextCell::paint_str(Red.normal(), "1000");
assert_eq!(expected, user.render(&details.colours, &MockUsers::with_current_uid(0))); assert_eq!(expected, user.render(&colours, &MockUsers::with_current_uid(0)));
} }
#[test] #[test]
fn overflow() { fn overflow() {
let mut details = Details::default(); let mut colours = Colours::default();
details.colours.users.user_someone_else = Blue.underline(); colours.users.user_someone_else = Blue.underline();
let user = f::User(2_147_483_648); let user = f::User(2_147_483_648);
let expected = TextCell::paint_str(Blue.underline(), "2147483648"); let expected = TextCell::paint_str(Blue.underline(), "2147483648");
assert_eq!(expected, user.render(&details.colours, &MockUsers::with_current_uid(0))); assert_eq!(expected, user.render(&colours, &MockUsers::with_current_uid(0)));
} }
} }