From 89bcc00e323c37d82d8fe0c924d281a25e8bfbf3 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 22:18:46 -0400 Subject: [PATCH 01/18] Upgrade to latest stable Rust and edition 2021 --- Cargo.toml | 4 ++-- rust-toolchain.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 965caab..10dea67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ name = "exa" description = "A modern replacement for ls" authors = ["Benjamin Sago "] categories = ["command-line-utilities"] -edition = "2018" -rust-version = "1.56.1" +edition = "2021" +rust-version = "1.63.0" exclude = ["/devtools/*", "/Justfile", "/Vagrantfile", "/screenshots.png"] readme = "README.md" homepage = "https://the.exa.website/" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 071aaaa..6a423bf 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.56.1" +channel = "1.63.0" From cd715a6e0036aa474a33d1f4735be27674a8c704 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 22:46:59 -0400 Subject: [PATCH 02/18] Safely derive `Eq` whenever we derive `PartialEq` --- src/fs/dir.rs | 2 +- src/fs/dir_action.rs | 4 ++-- src/fs/fields.rs | 2 +- src/fs/filter.rs | 10 +++++----- src/info/filetype.rs | 2 +- src/options/error.rs | 6 +++--- src/options/help.rs | 2 +- src/options/mod.rs | 2 +- src/options/parser.rs | 16 ++++++++-------- src/options/version.rs | 2 +- src/output/cell.rs | 2 +- src/output/details.rs | 2 +- src/output/file_name.rs | 4 ++-- src/output/grid.rs | 2 +- src/output/grid_details.rs | 4 ++-- src/output/mod.rs | 4 ++-- src/output/table.rs | 12 ++++++------ src/output/time.rs | 2 +- src/output/tree.rs | 2 +- src/theme/mod.rs | 8 ++++---- 20 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/fs/dir.rs b/src/fs/dir.rs index fcb393f..9d4d4f2 100644 --- a/src/fs/dir.rs +++ b/src/fs/dir.rs @@ -176,7 +176,7 @@ impl<'dir, 'ig> Iterator for Files<'dir, 'ig> { /// Usually files in Unix use a leading dot to be hidden or visible, but two /// entries in particular are “extra-hidden”: `.` and `..`, which only become /// visible after an extra `-a` option. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum DotFilter { /// Shows files, dotfiles, and `.` and `..`. diff --git a/src/fs/dir_action.rs b/src/fs/dir_action.rs index ab8ceda..6e10403 100644 --- a/src/fs/dir_action.rs +++ b/src/fs/dir_action.rs @@ -19,7 +19,7 @@ /// into them and print out their contents. The recurse mode does this by /// having extra output blocks at the end, while the tree mode will show /// directories inline, with their contents immediately underneath. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum DirAction { /// This directory should be listed along with the regular files, instead @@ -58,7 +58,7 @@ impl DirAction { /// The options that determine how to recurse into a directory. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub struct RecurseOptions { /// Whether recursion should be done as a tree or as multiple individual diff --git a/src/fs/fields.rs b/src/fs/fields.rs index 6ad41e3..9369ecb 100644 --- a/src/fs/fields.rs +++ b/src/fs/fields.rs @@ -210,7 +210,7 @@ pub struct Time { /// A file’s status in a Git repository. Whether a file is in a repository or /// not is handled by the Git module, rather than having a “null” variant in /// this enum. -#[derive(PartialEq, Copy, Clone)] +#[derive(PartialEq, Eq, Copy, Clone)] pub enum GitStatus { /// This file hasn’t changed since the last commit. diff --git a/src/fs/filter.rs b/src/fs/filter.rs index 9662931..d3f831b 100644 --- a/src/fs/filter.rs +++ b/src/fs/filter.rs @@ -23,7 +23,7 @@ use crate::fs::File; /// The filter also governs sorting the list. After being filtered, pairs of /// files are compared and sorted based on the result, with the sort field /// performing the comparison. -#[derive(PartialEq, Debug, Clone)] +#[derive(PartialEq, Eq, Debug, Clone)] pub struct FileFilter { /// Whether directories should be listed first, and other types of file @@ -113,7 +113,7 @@ impl FileFilter { /// User-supplied field to sort by. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum SortField { /// Don’t apply any sorting. This is usually used as an optimisation in @@ -194,7 +194,7 @@ pub enum SortField { /// lowercase letters because it takes the difference between the two cases /// into account? I gave up and just named these two variants after the /// effects they have. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum SortCase { /// Sort files case-sensitively with uppercase first, with ‘A’ coming @@ -271,7 +271,7 @@ impl SortField { /// The **ignore patterns** are a list of globs that are tested against /// each filename, and if any of them match, that file isn’t displayed. /// This lets a user hide, say, text files by ignoring `*.txt`. -#[derive(PartialEq, Default, Debug, Clone)] +#[derive(PartialEq, Eq, Default, Debug, Clone)] pub struct IgnorePatterns { patterns: Vec, } @@ -327,7 +327,7 @@ impl IgnorePatterns { /// Whether to ignore or display files that Git would ignore. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum GitIgnore { /// Ignore files that Git would ignore. diff --git a/src/info/filetype.rs b/src/info/filetype.rs index d7d2a4d..9223fdc 100644 --- a/src/info/filetype.rs +++ b/src/info/filetype.rs @@ -11,7 +11,7 @@ use crate::output::icons::FileIcon; use crate::theme::FileColours; -#[derive(Debug, Default, PartialEq)] +#[derive(Debug, Default, PartialEq, Eq)] pub struct FileExtensions; impl FileExtensions { diff --git a/src/options/error.rs b/src/options/error.rs index 1b1aa87..2721282 100644 --- a/src/options/error.rs +++ b/src/options/error.rs @@ -7,7 +7,7 @@ use crate::options::parser::{Arg, Flag, ParseError}; /// Something wrong with the combination of options the user has picked. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub enum OptionsError { /// There was an error (from `getopts`) parsing the arguments. @@ -44,7 +44,7 @@ pub enum OptionsError { } /// The source of a string that failed to be parsed as a number. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub enum NumberSource { /// It came... from a command-line argument! @@ -119,7 +119,7 @@ impl OptionsError { /// A list of legal choices for an argument-taking option. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct Choices(pub &'static [&'static str]); impl fmt::Display for Choices { diff --git a/src/options/help.rs b/src/options/help.rs index f3f4009..0299393 100644 --- a/src/options/help.rs +++ b/src/options/help.rs @@ -69,7 +69,7 @@ static EXTENDED_HELP: &str = " -@, --extended list each file's extended /// All the information needed to display the help text, which depends /// on which features are enabled and whether the user only wants to /// see one section’s help. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub struct HelpString; impl HelpString { diff --git a/src/options/mod.rs b/src/options/mod.rs index 528ba43..5c060b6 100644 --- a/src/options/mod.rs +++ b/src/options/mod.rs @@ -216,7 +216,7 @@ pub mod test { use crate::options::parser::{Arg, MatchedFlags}; use std::ffi::OsStr; - #[derive(PartialEq, Debug)] + #[derive(PartialEq, Eq, Debug)] pub enum Strictnesses { Last, Complain, diff --git a/src/options/parser.rs b/src/options/parser.rs index 63a1606..ca0029b 100644 --- a/src/options/parser.rs +++ b/src/options/parser.rs @@ -52,7 +52,7 @@ pub type Values = &'static [&'static str]; /// A **flag** is either of the two argument types, because they have to /// be in the same array together. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum Flag { Short(ShortArg), Long(LongArg), @@ -77,7 +77,7 @@ impl fmt::Display for Flag { } /// Whether redundant arguments should be considered a problem. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum Strictness { /// Throw an error when an argument doesn’t do anything, either because @@ -91,7 +91,7 @@ pub enum Strictness { /// Whether a flag takes a value. This is applicable to both long and short /// arguments. -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum TakesValue { /// This flag has to be followed by a value. @@ -108,7 +108,7 @@ pub enum TakesValue { /// An **argument** can be matched by one of the user’s input strings. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub struct Arg { /// The short argument that matches it, if any. @@ -136,7 +136,7 @@ impl fmt::Display for Arg { /// Literally just several args. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct Args(pub &'static [&'static Arg]); impl Args { @@ -340,7 +340,7 @@ impl Args { /// The **matches** are the result of parsing the user’s command-line strings. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct Matches<'args> { /// The flags that were parsed from the user’s input. @@ -351,7 +351,7 @@ pub struct Matches<'args> { pub frees: Vec<&'args OsStr>, } -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct MatchedFlags<'args> { /// The individual flags from the user’s input, in the order they were @@ -462,7 +462,7 @@ impl<'a> MatchedFlags<'a> { /// A problem with the user’s input that meant it couldn’t be parsed into a /// coherent list of arguments. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub enum ParseError { /// A flag that has to take a value was not given one. diff --git a/src/options/version.rs b/src/options/version.rs index 2214164..3b78c3a 100644 --- a/src/options/version.rs +++ b/src/options/version.rs @@ -8,7 +8,7 @@ use crate::options::flags; use crate::options::parser::MatchedFlags; -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub struct VersionString; // There were options here once, but there aren’t anymore! diff --git a/src/output/cell.rs b/src/output/cell.rs index c8d2675..f515014 100644 --- a/src/output/cell.rs +++ b/src/output/cell.rs @@ -193,7 +193,7 @@ impl TextCellContents { /// /// It has `From` impls that convert an input string or fixed with to values /// of this type, and will `Deref` to the contained `usize` value. -#[derive(PartialEq, Debug, Clone, Copy, Default)] +#[derive(PartialEq, Eq, Debug, Clone, Copy, Default)] pub struct DisplayWidth(usize); impl<'a> From<&'a str> for DisplayWidth { diff --git a/src/output/details.rs b/src/output/details.rs index 62ef7d8..f86a202 100644 --- a/src/output/details.rs +++ b/src/output/details.rs @@ -91,7 +91,7 @@ use crate::theme::Theme; /// /// Almost all the heavy lifting is done in a Table object, which handles the /// columns for each row. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct Options { /// Options specific to drawing a table. diff --git a/src/output/file_name.rs b/src/output/file_name.rs index eeb359b..6eeaf1b 100644 --- a/src/output/file_name.rs +++ b/src/output/file_name.rs @@ -54,7 +54,7 @@ enum LinkStyle { /// Whether to append file class characters to the file names. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum Classify { /// Just display the file names, without any characters. @@ -73,7 +73,7 @@ impl Default for Classify { /// Whether and how to show icons. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum ShowIcons { /// Don’t show icons at all. diff --git a/src/output/grid.rs b/src/output/grid.rs index 0e1b694..f53ccfa 100644 --- a/src/output/grid.rs +++ b/src/output/grid.rs @@ -8,7 +8,7 @@ use crate::output::file_name::Options as FileStyle; use crate::theme::Theme; -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub struct Options { pub across: bool, } diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs index fd096da..94c1b79 100644 --- a/src/output/grid_details.rs +++ b/src/output/grid_details.rs @@ -18,7 +18,7 @@ use crate::output::tree::{TreeParams, TreeDepth}; use crate::theme::Theme; -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct Options { pub grid: GridOptions, pub details: DetailsOptions, @@ -39,7 +39,7 @@ impl Options { /// small directory of four files in four columns, the files just look spaced /// out and it’s harder to see what’s going on. So it can be enabled just for /// larger directory listings. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum RowThreshold { /// Only use grid-details view if it would result in at least this many diff --git a/src/output/mod.rs b/src/output/mod.rs index 2c64010..331d2fd 100644 --- a/src/output/mod.rs +++ b/src/output/mod.rs @@ -26,7 +26,7 @@ pub struct View { /// The **mode** is the “type” of output. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] #[allow(clippy::large_enum_variant)] pub enum Mode { Grid(grid::Options), @@ -37,7 +37,7 @@ pub enum Mode { /// The width of the terminal requested by the user. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum TerminalWidth { /// The user requested this specific number of columns. diff --git a/src/output/table.rs b/src/output/table.rs index 6bd1f8e..b502c52 100644 --- a/src/output/table.rs +++ b/src/output/table.rs @@ -21,7 +21,7 @@ use crate::theme::Theme; /// Options for displaying a table. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct Options { pub size_format: SizeFormat, pub time_format: TimeFormat, @@ -31,7 +31,7 @@ pub struct Options { /// Extra columns to display in the table. #[allow(clippy::struct_excessive_bools)] -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub struct Columns { /// At least one of these timestamps will be shown. @@ -201,7 +201,7 @@ impl Column { /// Formatting options for file sizes. #[allow(clippy::pub_enum_variant_names)] -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum SizeFormat { /// Format the file size using **decimal** prefixes, such as “kilo”, @@ -217,7 +217,7 @@ pub enum SizeFormat { } /// Formatting options for user and group. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum UserFormat { /// The UID / GID Numeric, @@ -234,7 +234,7 @@ impl Default for SizeFormat { /// The types of a file’s time fields. These three fields are standard /// across most (all?) operating systems. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum TimeType { /// The file’s modified time (`st_mtime`). @@ -269,7 +269,7 @@ impl TimeType { /// /// There should always be at least one of these — there’s no way to disable /// the time columns entirely (yet). -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] #[allow(clippy::struct_excessive_bools)] pub struct TimeTypes { pub modified: bool, diff --git a/src/output/time.rs b/src/output/time.rs index cb18c54..bb3ee61 100644 --- a/src/output/time.rs +++ b/src/output/time.rs @@ -25,7 +25,7 @@ use unicode_width::UnicodeWidthStr; /// /// Currently exa does not support *custom* styles, where the user enters a /// format string in an environment variable or something. Just these four. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum TimeFormat { /// The **default format** uses the user’s locale to print month names, diff --git a/src/output/tree.rs b/src/output/tree.rs index 209b82c..360a8c4 100644 --- a/src/output/tree.rs +++ b/src/output/tree.rs @@ -39,7 +39,7 @@ //! each directory) -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum TreePart { /// Rightmost column, *not* the last in the directory. diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 6f282d9..243698e 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -14,7 +14,7 @@ pub use self::lsc::LSColors; mod default_theme; -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Eq, Debug)] pub struct Options { pub use_colours: UseColours, @@ -31,7 +31,7 @@ pub struct Options { /// Turning them on when output is going to, say, a pipe, would make programs /// such as `grep` or `more` not work properly. So the `Automatic` mode does /// this check and only displays colours when they can be truly appreciated. -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum UseColours { /// Display them even when output isn’t going to a terminal. @@ -44,13 +44,13 @@ pub enum UseColours { Never, } -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum ColourScale { Fixed, Gradient, } -#[derive(PartialEq, Debug, Default)] +#[derive(PartialEq, Eq, Debug, Default)] pub struct Definitions { pub ls: Option, pub exa: Option, From af267ba638b1d8af723ab366aaaf88255887888c Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 22:55:37 -0400 Subject: [PATCH 03/18] Use `unwrap_or_else` in build.rs --- build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.rs b/build.rs index a0a1351..6cd6c72 100644 --- a/build.rs +++ b/build.rs @@ -41,7 +41,7 @@ fn main() -> io::Result<()> { let path = &out.join("version_string.txt"); // Bland version text - let mut f = File::create(path).expect(&path.to_string_lossy()); + let mut f = File::create(path).unwrap_or_else(|_| { panic!("{}", path.to_string_lossy().to_string()) }); writeln!(f, "{}", strip_codes(&ver))?; Ok(()) From 1b844a8dfa5f16cf82f49a855e25b1833f9fd2ff Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 22:56:50 -0400 Subject: [PATCH 04/18] Change `pub_enum_variant_names` lint to `enum_variant_names` --- src/output/table.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output/table.rs b/src/output/table.rs index b502c52..548d1c1 100644 --- a/src/output/table.rs +++ b/src/output/table.rs @@ -200,7 +200,7 @@ impl Column { /// Formatting options for file sizes. -#[allow(clippy::pub_enum_variant_names)] +#[allow(clippy::enum_variant_names)] #[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum SizeFormat { From 2917062466183d7db9e4bf72a68599fa34836ee2 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:05:39 -0400 Subject: [PATCH 05/18] Nest OR patterns in match arms --- src/theme/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 243698e..f167b7b 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -263,9 +263,9 @@ impl render::SizeColours for Theme { match prefix { None => self.ui.size.number_byte, - Some(Kilo) | Some(Kibi) => self.ui.size.number_kilo, - Some(Mega) | Some(Mebi) => self.ui.size.number_mega, - Some(Giga) | Some(Gibi) => self.ui.size.number_giga, + Some(Kilo | Kibi) => self.ui.size.number_kilo, + Some(Mega | Mebi) => self.ui.size.number_mega, + Some(Giga | Gibi) => self.ui.size.number_giga, Some(_) => self.ui.size.number_huge, } } @@ -275,9 +275,9 @@ impl render::SizeColours for Theme { match prefix { None => self.ui.size.unit_byte, - Some(Kilo) | Some(Kibi) => self.ui.size.unit_kilo, - Some(Mega) | Some(Mebi) => self.ui.size.unit_mega, - Some(Giga) | Some(Gibi) => self.ui.size.unit_giga, + Some(Kilo | Kibi) => self.ui.size.unit_kilo, + Some(Mega | Mebi) => self.ui.size.unit_mega, + Some(Giga | Gibi) => self.ui.size.unit_giga, Some(_) => self.ui.size.unit_huge, } } From 75952896982078cb61117d3d4df77491ce87c10a Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:06:08 -0400 Subject: [PATCH 06/18] Use `unsigned_abs` instead of casting from i64 to u64 --- src/fs/file.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fs/file.rs b/src/fs/file.rs index 7112109..81eee3d 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -375,7 +375,7 @@ impl<'dir> File<'dir> { nanosec -= 1_000_000_000; } - let duration = Duration::new(sec.abs() as u64, nanosec.abs() as u32); + let duration = Duration::new(sec.unsigned_abs(), nanosec.unsigned_abs() as u32); Some(UNIX_EPOCH - duration) } else { From 19601267cf425d3e5fbc99788834f5b5dda0056d Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:10:57 -0400 Subject: [PATCH 07/18] Convert from bool to u8 using From trait --- src/output/render/octal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output/render/octal.rs b/src/output/render/octal.rs index 1c3eb07..454f756 100644 --- a/src/output/render/octal.rs +++ b/src/output/render/octal.rs @@ -6,7 +6,7 @@ use crate::output::cell::TextCell; impl f::OctalPermissions { fn bits_to_octal(r: bool, w: bool, x: bool) -> u8 { - (r as u8) * 4 + (w as u8) * 2 + (x as u8) + u8::from(r) * 4 + u8::from(w) * 2 + u8::from(x) } pub fn render(&self, style: Style) -> TextCell { From 1f409793ae8eb0aa39dabc1bfb09333c20e2fee1 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:15:53 -0400 Subject: [PATCH 08/18] Use `pointer::cast` instead of `as` pointer casts --- src/fs/feature/xattr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fs/feature/xattr.rs b/src/fs/feature/xattr.rs index 65b8c95..192371c 100644 --- a/src/fs/feature/xattr.rs +++ b/src/fs/feature/xattr.rs @@ -167,7 +167,7 @@ mod lister { unsafe { listxattr( c_path.as_ptr(), - buf.as_mut_ptr() as *mut c_char, + buf.as_mut_ptr().cast::(), bufsize as size_t, self.c_flags, ) @@ -178,7 +178,7 @@ mod lister { unsafe { getxattr( c_path.as_ptr(), - buf.as_ptr() as *const c_char, + buf.as_ptr().cast::(), ptr::null_mut(), 0, 0, From 7c1878f0e4486365fba4c5bfe11fb55f23c51360 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:20:01 -0400 Subject: [PATCH 09/18] Fix borrowing code smells --- src/fs/file.rs | 6 +++--- src/output/details.rs | 2 +- src/output/grid_details.rs | 2 +- src/output/time.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fs/file.rs b/src/fs/file.rs index 81eee3d..bccc655 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -221,13 +221,13 @@ impl<'dir> File<'dir> { path.to_path_buf() } else if let Some(dir) = self.parent_dir { - dir.join(&*path) + dir.join(path) } else if let Some(parent) = self.path.parent() { - parent.join(&*path) + parent.join(path) } else { - self.path.join(&*path) + self.path.join(path) } } diff --git a/src/output/details.rs b/src/output/details.rs index f86a202..b729ceb 100644 --- a/src/output/details.rs +++ b/src/output/details.rs @@ -161,7 +161,7 @@ impl<'a> Render<'a> { (None, _) => {/* Keep Git how it is */}, } - let mut table = Table::new(table, self.git, &self.theme); + let mut table = Table::new(table, self.git, self.theme); if self.opts.header { let header = table.header_row(); diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs index 94c1b79..f277f3e 100644 --- a/src/output/grid_details.rs +++ b/src/output/grid_details.rs @@ -202,7 +202,7 @@ impl<'a> Render<'a> { (None, _) => {/* Keep Git how it is */}, } - let mut table = Table::new(options, self.git, &self.theme); + let mut table = Table::new(options, self.git, self.theme); let mut rows = Vec::new(); if self.details.header { diff --git a/src/output/time.rs b/src/output/time.rs index bb3ee61..081333f 100644 --- a/src/output/time.rs +++ b/src/output/time.rs @@ -87,7 +87,7 @@ fn default_zoned(time: SystemTime, zone: &TimeZone) -> String { } fn get_dateformat(date: &LocalDateTime) -> &'static DateFormat<'static> { - match (is_recent(&date), *MAXIMUM_MONTH_WIDTH) { + match (is_recent(date), *MAXIMUM_MONTH_WIDTH) { (true, 4) => &FOUR_WIDE_DATE_TIME, (true, 5) => &FIVE_WIDE_DATE_TIME, (true, _) => &OTHER_WIDE_DATE_TIME, From 433a9a52d3701b0ca699cce5244368e25eef3081 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:26:44 -0400 Subject: [PATCH 10/18] Use mutable slice instead of creating new Vec in filters --- src/fs/filter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fs/filter.rs b/src/fs/filter.rs index d3f831b..84f607c 100644 --- a/src/fs/filter.rs +++ b/src/fs/filter.rs @@ -89,7 +89,7 @@ impl FileFilter { } /// Sort the files in the given vector based on the sort field option. - pub fn sort_files<'a, F>(&self, files: &mut Vec) + pub fn sort_files<'a, F>(&self, files: &mut [F]) where F: AsRef> { files.sort_by(|a, b| { From d24ca084a35f75e96fb3d50ac5cce348e9947dbd Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:31:47 -0400 Subject: [PATCH 11/18] Use single char pattern for better performance --- src/output/table.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output/table.rs b/src/output/table.rs index 548d1c1..06e13b9 100644 --- a/src/output/table.rs +++ b/src/output/table.rs @@ -347,7 +347,7 @@ fn determine_time_zone() -> TZResult { } else { format!("/usr/share/zoneinfo/{}", { if file.starts_with(':') { - file.replacen(":", "", 1) + file.replacen(':', "", 1) } else { file } From 1dc14eaff14b6d33b2ef8041add7b804bf303970 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:33:17 -0400 Subject: [PATCH 12/18] Avoid manually implementing repeat() with iterators --- src/output/cell.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/output/cell.rs b/src/output/cell.rs index f515014..959be4f 100644 --- a/src/output/cell.rs +++ b/src/output/cell.rs @@ -77,11 +77,9 @@ impl TextCell { /// /// This method allocates a `String` to hold the spaces. pub fn add_spaces(&mut self, count: usize) { - use std::iter::repeat; - (*self.width) += count; - let spaces: String = repeat(' ').take(count).collect(); + let spaces: String = " ".repeat(count); self.contents.0.push(Style::default().paint(spaces)); } From bbea87db91cb4f3a7b284296f7853ce16fb6b54d Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:34:05 -0400 Subject: [PATCH 13/18] Avoid redundant closures when calling methods --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 7dcff10..db09619 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,7 +62,7 @@ fn main() { } let args: Vec<_> = env::args_os().skip(1).collect(); - match Options::parse(args.iter().map(|e| e.as_ref()), &LiveVars) { + match Options::parse(args.iter().map(std::convert::AsRef::as_ref), &LiveVars) { OptionsResult::Ok(options, mut input_paths) => { // List the current directory by default. From 72b2119a34af99dffd88044a55253d4229dfc669 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:43:14 -0400 Subject: [PATCH 14/18] Simplify boolean assertions in tests --- src/fs/filter.rs | 16 ++++++++-------- src/options/parser.rs | 2 +- src/output/tree.rs | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/fs/filter.rs b/src/fs/filter.rs index 84f607c..4cd08b0 100644 --- a/src/fs/filter.rs +++ b/src/fs/filter.rs @@ -346,31 +346,31 @@ mod test_ignores { #[test] fn empty_matches_nothing() { let pats = IgnorePatterns::empty(); - assert_eq!(false, pats.is_ignored("nothing")); - assert_eq!(false, pats.is_ignored("test.mp3")); + assert!(!pats.is_ignored("nothing")); + assert!(!pats.is_ignored("test.mp3")); } #[test] fn ignores_a_glob() { let (pats, fails) = IgnorePatterns::parse_from_iter(vec![ "*.mp3" ]); assert!(fails.is_empty()); - assert_eq!(false, pats.is_ignored("nothing")); - assert_eq!(true, pats.is_ignored("test.mp3")); + assert!(!pats.is_ignored("nothing")); + assert!(pats.is_ignored("test.mp3")); } #[test] fn ignores_an_exact_filename() { let (pats, fails) = IgnorePatterns::parse_from_iter(vec![ "nothing" ]); assert!(fails.is_empty()); - assert_eq!(true, pats.is_ignored("nothing")); - assert_eq!(false, pats.is_ignored("test.mp3")); + assert!(pats.is_ignored("nothing")); + assert!(!pats.is_ignored("test.mp3")); } #[test] fn ignores_both() { let (pats, fails) = IgnorePatterns::parse_from_iter(vec![ "nothing", "*.mp3" ]); assert!(fails.is_empty()); - assert_eq!(true, pats.is_ignored("nothing")); - assert_eq!(true, pats.is_ignored("test.mp3")); + assert!(pats.is_ignored("nothing")); + assert!(pats.is_ignored("test.mp3")); } } diff --git a/src/options/parser.rs b/src/options/parser.rs index ca0029b..7f6e388 100644 --- a/src/options/parser.rs +++ b/src/options/parser.rs @@ -743,6 +743,6 @@ mod matches_test { fn no_count() { let flags = MatchedFlags { flags: Vec::new(), strictness: Strictness::UseLastArguments }; - assert_eq!(flags.has(&COUNT).unwrap(), false); + assert!(!flags.has(&COUNT).unwrap()); } } diff --git a/src/output/tree.rs b/src/output/tree.rs index 360a8c4..5e27e20 100644 --- a/src/output/tree.rs +++ b/src/output/tree.rs @@ -257,15 +257,15 @@ mod iter_test { let next = iter.next().unwrap(); assert_eq!(&"first", next.1); - assert_eq!(false, next.0.last); + assert!(!next.0.last); let next = iter.next().unwrap(); assert_eq!(&"middle", next.1); - assert_eq!(false, next.0.last); + assert!(!next.0.last); let next = iter.next().unwrap(); assert_eq!(&"last", next.1); - assert_eq!(true, next.0.last); + assert!(next.0.last); assert!(iter.next().is_none()); } From eba3646b8383102abee2654c8bc24389eb4a593a Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 30 Sep 2022 23:50:31 -0400 Subject: [PATCH 15/18] Grab bag of miscellaneous fixes --- src/options/filter.rs | 2 +- src/options/mod.rs | 4 ++-- src/options/theme.rs | 8 ++++---- src/options/view.rs | 4 ++-- src/output/render/blocks.rs | 4 ++-- src/output/render/git.rs | 4 ++-- src/output/render/inode.rs | 4 ++-- src/output/render/links.rs | 6 +++--- src/output/render/octal.rs | 12 ++++++------ src/output/render/size.rs | 2 +- src/output/tree.rs | 4 ++-- 11 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/options/filter.rs b/src/options/filter.rs index ad88ff7..75e10fe 100644 --- a/src/options/filter.rs +++ b/src/options/filter.rs @@ -295,7 +295,7 @@ mod test { mod ignore_patterns { use super::*; use std::iter::FromIterator; - use glob; + fn pat(string: &'static str) -> glob::Pattern { glob::Pattern::new(string).unwrap() diff --git a/src/options/mod.rs b/src/options/mod.rs index 5c060b6..c203176 100644 --- a/src/options/mod.rs +++ b/src/options/mod.rs @@ -228,14 +228,14 @@ pub mod test { /// both, then both should resolve to the same result. /// /// It returns a vector with one or two elements in. - /// These elements can then be tested with assert_eq or what have you. + /// These elements can then be tested with `assert_eq` or what have you. pub fn parse_for_test(inputs: &[&str], args: &'static [&'static Arg], strictnesses: Strictnesses, get: F) -> Vec where F: Fn(&MatchedFlags<'_>) -> T { use self::Strictnesses::*; use crate::options::parser::{Args, Strictness}; - let bits = inputs.into_iter().map(OsStr::new).collect::>(); + let bits = inputs.iter().map(OsStr::new).collect::>(); let mut result = Vec::new(); if strictnesses == Last || strictnesses == Both { diff --git a/src/options/theme.rs b/src/options/theme.rs index 010de4a..5d27173 100644 --- a/src/options/theme.rs +++ b/src/options/theme.rs @@ -130,18 +130,18 @@ mod terminal_test { impl MockVars { fn empty() -> MockVars { - return MockVars { + MockVars { ls: "", exa: "", no_color: "", - }; + } } fn with_no_color() -> MockVars { - return MockVars { + MockVars { ls: "", exa: "", no_color: "true", - }; + } } } diff --git a/src/options/view.rs b/src/options/view.rs index 41816fb..078d4a6 100644 --- a/src/options/view.rs +++ b/src/options/view.rs @@ -378,7 +378,7 @@ mod test { ($name:ident: $type:ident <- $inputs:expr; $stricts:expr => err $result:expr) => { /// Special macro for testing Err results. - /// This is needed because sometimes the Ok type doesn’t implement PartialEq. + /// This is needed because sometimes the Ok type doesn’t implement `PartialEq`. #[test] fn $name() { for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| $type::deduce(mf)) { @@ -389,7 +389,7 @@ mod test { ($name:ident: $type:ident <- $inputs:expr; $stricts:expr => like $pat:pat) => { /// More general macro for testing against a pattern. - /// Instead of using PartialEq, this just tests if it matches a pat. + /// Instead of using `PartialEq`, this just tests if it matches a pat. #[test] fn $name() { for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| $type::deduce(mf)) { diff --git a/src/output/render/blocks.rs b/src/output/render/blocks.rs index 5745f8f..cd5182d 100644 --- a/src/output/render/blocks.rs +++ b/src/output/render/blocks.rs @@ -43,7 +43,7 @@ pub mod test { let blox = f::Blocks::None; let expected = TextCell::blank(Green.italic()); - assert_eq!(expected, blox.render(&TestColours).into()); + assert_eq!(expected, blox.render(&TestColours)); } @@ -52,6 +52,6 @@ pub mod test { let blox = f::Blocks::Some(3005); let expected = TextCell::paint_str(Red.blink(), "3005"); - assert_eq!(expected, blox.render(&TestColours).into()); + assert_eq!(expected, blox.render(&TestColours)); } } diff --git a/src/output/render/git.rs b/src/output/render/git.rs index 3740d40..ae96e58 100644 --- a/src/output/render/git.rs +++ b/src/output/render/git.rs @@ -85,7 +85,7 @@ pub mod test { ].into(), }; - assert_eq!(expected, stati.render(&TestColours).into()) + assert_eq!(expected, stati.render(&TestColours)) } @@ -104,6 +104,6 @@ pub mod test { ].into(), }; - assert_eq!(expected, stati.render(&TestColours).into()) + assert_eq!(expected, stati.render(&TestColours)) } } diff --git a/src/output/render/inode.rs b/src/output/render/inode.rs index 7737aa2..8bb3249 100644 --- a/src/output/render/inode.rs +++ b/src/output/render/inode.rs @@ -21,8 +21,8 @@ pub mod test { #[test] fn blocklessness() { - let io = f::Inode(1414213); + let io = f::Inode(1_414_213); let expected = TextCell::paint_str(Cyan.underline(), "1414213"); - assert_eq!(expected, io.render(Cyan.underline()).into()); + assert_eq!(expected, io.render(Cyan.underline())); } } diff --git a/src/output/render/links.rs b/src/output/render/links.rs index 19b5f18..612a5d3 100644 --- a/src/output/render/links.rs +++ b/src/output/render/links.rs @@ -52,7 +52,7 @@ pub mod test { contents: vec![ Blue.paint("1") ].into(), }; - assert_eq!(expected, stati.render(&TestColours, &locale::Numeric::english()).into()); + assert_eq!(expected, stati.render(&TestColours, &locale::Numeric::english())); } #[test] @@ -67,7 +67,7 @@ pub mod test { contents: vec![ Blue.paint("3,005") ].into(), }; - assert_eq!(expected, stati.render(&TestColours, &locale::Numeric::english()).into()); + assert_eq!(expected, stati.render(&TestColours, &locale::Numeric::english())); } #[test] @@ -82,6 +82,6 @@ pub mod test { contents: vec![ Blue.on(Red).paint("3,005") ].into(), }; - assert_eq!(expected, stati.render(&TestColours, &locale::Numeric::english()).into()); + assert_eq!(expected, stati.render(&TestColours, &locale::Numeric::english())); } } diff --git a/src/output/render/octal.rs b/src/output/render/octal.rs index 454f756..5bb64b5 100644 --- a/src/output/render/octal.rs +++ b/src/output/render/octal.rs @@ -40,7 +40,7 @@ pub mod test { let octal = f::OctalPermissions{ permissions: bits }; let expected = TextCell::paint_str(Purple.bold(), "0755"); - assert_eq!(expected, octal.render(Purple.bold()).into()); + assert_eq!(expected, octal.render(Purple.bold())); } #[test] @@ -54,7 +54,7 @@ pub mod test { let octal = f::OctalPermissions{ permissions: bits }; let expected = TextCell::paint_str(Purple.bold(), "0644"); - assert_eq!(expected, octal.render(Purple.bold()).into()); + assert_eq!(expected, octal.render(Purple.bold())); } #[test] @@ -68,7 +68,7 @@ pub mod test { let octal = f::OctalPermissions{ permissions: bits }; let expected = TextCell::paint_str(Purple.bold(), "0600"); - assert_eq!(expected, octal.render(Purple.bold()).into()); + assert_eq!(expected, octal.render(Purple.bold())); } #[test] @@ -82,7 +82,7 @@ pub mod test { let octal = f::OctalPermissions{ permissions: bits }; let expected = TextCell::paint_str(Purple.bold(), "4777"); - assert_eq!(expected, octal.render(Purple.bold()).into()); + assert_eq!(expected, octal.render(Purple.bold())); } @@ -97,7 +97,7 @@ pub mod test { let octal = f::OctalPermissions{ permissions: bits }; let expected = TextCell::paint_str(Purple.bold(), "2777"); - assert_eq!(expected, octal.render(Purple.bold()).into()); + assert_eq!(expected, octal.render(Purple.bold())); } #[test] @@ -111,6 +111,6 @@ pub mod test { let octal = f::OctalPermissions{ permissions: bits }; let expected = TextCell::paint_str(Purple.bold(), "1777"); - assert_eq!(expected, octal.render(Purple.bold()).into()); + assert_eq!(expected, octal.render(Purple.bold())); } } diff --git a/src/output/render/size.rs b/src/output/render/size.rs index 5a3ad72..716cc48 100644 --- a/src/output/render/size.rs +++ b/src/output/render/size.rs @@ -153,7 +153,7 @@ pub mod test { #[test] fn file_bytes() { - let directory = f::Size::Some(1048576); + let directory = f::Size::Some(1_048_576); let expected = TextCell { width: DisplayWidth::from(9), contents: vec![ diff --git a/src/output/tree.rs b/src/output/tree.rs index 5e27e20..c3bff43 100644 --- a/src/output/tree.rs +++ b/src/output/tree.rs @@ -253,7 +253,7 @@ mod iter_test { #[test] fn test_iteration() { let foos = &[ "first", "middle", "last" ]; - let mut iter = TreeDepth::root().iterate_over(foos.into_iter()); + let mut iter = TreeDepth::root().iterate_over(foos.iter()); let next = iter.next().unwrap(); assert_eq!(&"first", next.1); @@ -273,7 +273,7 @@ mod iter_test { #[test] fn test_empty() { let nothing: &[usize] = &[]; - let mut iter = TreeDepth::root().iterate_over(nothing.into_iter()); + let mut iter = TreeDepth::root().iterate_over(nothing.iter()); assert!(iter.next().is_none()); } } From 8d03922e3bdb9f262b2719fd9de71ac2a1b449c5 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Fri, 24 Feb 2023 18:45:27 -0500 Subject: [PATCH 16/18] Addressed PR comments --- src/options/filter.rs | 1 - src/options/parser.rs | 2 +- src/theme/mod.rs | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/options/filter.rs b/src/options/filter.rs index 75e10fe..a23e59d 100644 --- a/src/options/filter.rs +++ b/src/options/filter.rs @@ -295,7 +295,6 @@ mod test { mod ignore_patterns { use super::*; use std::iter::FromIterator; - fn pat(string: &'static str) -> glob::Pattern { glob::Pattern::new(string).unwrap() diff --git a/src/options/parser.rs b/src/options/parser.rs index 7f6e388..8095237 100644 --- a/src/options/parser.rs +++ b/src/options/parser.rs @@ -91,7 +91,7 @@ pub enum Strictness { /// Whether a flag takes a value. This is applicable to both long and short /// arguments. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum TakesValue { /// This flag has to be followed by a value. diff --git a/src/theme/mod.rs b/src/theme/mod.rs index f167b7b..2eb29da 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -262,11 +262,11 @@ impl render::SizeColours for Theme { use number_prefix::Prefix::*; match prefix { - None => self.ui.size.number_byte, Some(Kilo | Kibi) => self.ui.size.number_kilo, Some(Mega | Mebi) => self.ui.size.number_mega, Some(Giga | Gibi) => self.ui.size.number_giga, - Some(_) => self.ui.size.number_huge, + Some(_) => self.ui.size.number_huge, + None => self.ui.size.number_byte, } } @@ -274,11 +274,11 @@ impl render::SizeColours for Theme { use number_prefix::Prefix::*; match prefix { - None => self.ui.size.unit_byte, Some(Kilo | Kibi) => self.ui.size.unit_kilo, Some(Mega | Mebi) => self.ui.size.unit_mega, Some(Giga | Gibi) => self.ui.size.unit_giga, - Some(_) => self.ui.size.unit_huge, + Some(_) => self.ui.size.unit_huge, + None => self.ui.size.unit_byte, } } From 39d15a317da39b6432a3eb1f161d61317095c2c8 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Tue, 28 Feb 2023 22:23:29 -0500 Subject: [PATCH 17/18] Update GitHub actions Rust version --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 05b7d54..a3309bc 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -28,7 +28,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - rust: [1.56.1, stable, beta, nightly] + rust: [1.63.0, stable, beta, nightly] steps: - name: Checkout repository From ee6711033354cc54fc3d970a0f9e59fe6003b4f7 Mon Sep 17 00:00:00 2001 From: Victor Song Date: Tue, 28 Feb 2023 22:41:51 -0500 Subject: [PATCH 18/18] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 157853b..4bf682c 100644 --- a/README.md +++ b/README.md @@ -196,8 +196,8 @@ To build without Git support, run `cargo install --no-default-features exa` is a

Development - - Rust 1.56.1+ + + Rust 1.63.0+