chore: update to Rust edition 2024

This commit is contained in:
ariasuni
2026-03-08 03:20:56 +01:00
parent 0bd1f46b6f
commit ec46fbf392
30 changed files with 162 additions and 170 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ name = "eza"
description = "A modern replacement for ls"
authors = ["Christina Sørensen <[email protected]>"]
categories = ["command-line-utilities"]
edition = "2021"
edition = "2024"
rust-version = "1.90"
exclude = [
"/docs/",
+1 -1
View File
@@ -6,7 +6,7 @@
// SPDX-License-Identifier: MIT
use std::hint::black_box;
use criterion::{criterion_group, criterion_main, Criterion};
use criterion::{Criterion, criterion_group, criterion_main};
pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("logger", |b| {
+6 -5
View File
@@ -71,7 +71,7 @@ impl FileAttributes for Path {
))]
mod extended_attrs {
use super::Attribute;
use libc::{c_char, c_void, size_t, ssize_t, ERANGE};
use libc::{ERANGE, c_char, c_void, size_t, ssize_t};
use std::ffi::{CStr, CString, OsStr, OsString};
use std::io;
use std::os::unix::ffi::OsStrExt;
@@ -81,8 +81,8 @@ mod extended_attrs {
#[cfg(target_os = "macos")]
mod os {
use libc::{
c_char, c_int, c_void, getxattr, listxattr, size_t, ssize_t, XATTR_NOFOLLOW,
XATTR_SHOWCOMPRESSION,
XATTR_NOFOLLOW, XATTR_SHOWCOMPRESSION, c_char, c_int, c_void, getxattr, listxattr,
size_t, ssize_t,
};
// Options to use for MacOS versions of getxattr and listxattr
@@ -161,8 +161,9 @@ mod extended_attrs {
#[cfg(any(target_os = "netbsd", target_os = "freebsd"))]
mod os {
use libc::{
c_char, c_int, c_void, extattr_get_file, extattr_get_link, extattr_list_file,
extattr_list_link, size_t, ssize_t, EXTATTR_NAMESPACE_SYSTEM, EXTATTR_NAMESPACE_USER,
EXTATTR_NAMESPACE_SYSTEM, EXTATTR_NAMESPACE_USER, c_char, c_int, c_void,
extattr_get_file, extattr_get_link, extattr_list_file, extattr_list_link, size_t,
ssize_t,
};
// Wrapper around listxattr that handles symbolic links
+1 -1
View File
@@ -35,8 +35,8 @@ use crate::fs::fields as f;
use crate::fs::fields::SecurityContextType;
use crate::fs::recursive_size::RecursiveSize;
use super::mounts::all_mounts;
use super::mounts::MountedFs;
use super::mounts::all_mounts;
// Maps (device_id, inode) => (size_in_bytes, size_in_blocks)
// Mutex::new is const but HashMap::new is not const requiring us to use lazy
+1 -1
View File
@@ -5,7 +5,7 @@
// SPDX-FileCopyrightText: 2014 Benjamin Sago
// SPDX-License-Identifier: MIT
use crate::fs::mounts::{Error, MountedFs};
use libc::{__error, getfsstat, statfs, MNT_NOWAIT};
use libc::{__error, MNT_NOWAIT, getfsstat, statfs};
use std::ffi::{CStr, OsStr};
use std::os::raw::{c_char, c_int};
use std::os::unix::ffi::OsStrExt;
+5 -6
View File
@@ -13,7 +13,7 @@
//! # Contributors
//! Please keep these lists sorted. If you're using vim, :sort i
use phf::{phf_map, Map};
use phf::{Map, phf_map};
use crate::fs::File;
@@ -429,14 +429,13 @@ impl FileType {
if file.name.ends_with('~') || (file.name.starts_with('#') && file.name.ends_with('#')) {
return Some(Self::Temp);
}
if let Some(dir) = file.parent_dir {
if file
if let Some(dir) = file.parent_dir
&& file
.get_source_files()
.iter()
.any(|path| dir.contains(path))
{
return Some(Self::Compiled);
}
{
return Some(Self::Compiled);
}
None
}
+8 -8
View File
@@ -11,7 +11,7 @@
use std::env;
use std::ffi::{OsStr, OsString};
use std::io::{self, stdin, ErrorKind, IsTerminal, Read, Write};
use std::io::{self, ErrorKind, IsTerminal, Read, Write, stdin};
use std::path::{Component, PathBuf};
use std::process::exit;
@@ -22,8 +22,8 @@ use crate::fs::feature::git::GitCache;
use crate::fs::filter::{FileFilterFlags::OnlyFiles, GitIgnore};
use crate::fs::{Dir, File};
use crate::options::stdin::FilesInput;
use crate::options::{vars, Options, Vars};
use crate::output::{details, escape, file_name, grid, grid_details, lines, Mode, View};
use crate::options::{Options, Vars, vars};
use crate::output::{Mode, View, details, escape, file_name, grid, grid_details, lines};
use crate::theme::Theme;
use log::*;
@@ -406,7 +406,7 @@ impl Exa<'_> {
} = self.options.view;
match (mode, self.console_width) {
(Mode::Grid(ref opts), Some(console_width)) => {
(Mode::Grid(opts), Some(console_width)) => {
let filter = &self.options.filter;
let r = grid::Render {
files,
@@ -419,7 +419,7 @@ impl Exa<'_> {
r.render(&mut self.writer)
}
(Mode::Grid(ref opts), None) => {
(Mode::Grid(opts), None) => {
let filter = &self.options.filter;
let r = grid::Render {
files,
@@ -443,7 +443,7 @@ impl Exa<'_> {
r.render(&mut self.writer)
}
(Mode::Details(ref opts), _) => {
(Mode::Details(opts), _) => {
let filter = &self.options.filter;
let recurse = self.options.dir_action.recurse_options();
@@ -465,7 +465,7 @@ impl Exa<'_> {
r.render(&mut self.writer)
}
(Mode::GridDetails(ref opts), Some(console_width)) => {
(Mode::GridDetails(opts), Some(console_width)) => {
let details = &opts.details;
let row_threshold = opts.row_threshold;
@@ -490,7 +490,7 @@ impl Exa<'_> {
r.render(&mut self.writer)
}
(Mode::GridDetails(ref opts), None) => {
(Mode::GridDetails(opts), None) => {
let opts = &opts.to_details_options();
let filter = &self.options.filter;
let recurse = self.options.dir_action.recurse_options();
+1 -1
View File
@@ -80,7 +80,7 @@ impl fmt::Display for OptionsError {
Self::Useless2(a, b1, b2) => write!(f, "Option {a} is useless without options {b1} or {b2}"),
Self::TreeAllAll => write!(f, "Option --tree is useless given --all --all"),
Self::FailedParse(s, n, e) => write!(f, "Value {s:?} not valid for {n}: {e}"),
Self::FailedGlobPattern(ref e) => write!(f, "Failed to parse glob pattern: {e}"),
Self::FailedGlobPattern(e) => write!(f, "Failed to parse glob pattern: {e}"),
};
}
}
+1 -1
View File
@@ -109,8 +109,8 @@ mod tests {
use std::num::ParseIntError;
use super::*;
use crate::options::parser::test::mock_cli;
use crate::options::parser::ShowWhen;
use crate::options::parser::test::mock_cli;
use crate::options::vars::test::MockVars;
use crate::output::file_name::Absolute;
+1 -1
View File
@@ -8,10 +8,10 @@
use clap::ArgMatches;
use crate::fs::DotFilter;
use crate::fs::filter::{
FileFilter, FileFilterFlags, GitIgnore, IgnorePatterns, SortCase, SortField,
};
use crate::fs::DotFilter;
use crate::options::OptionsError;
+1 -1
View File
@@ -79,7 +79,7 @@ use clap::ArgMatches;
use crate::fs::dir_action::DirAction;
use crate::fs::filter::{FileFilter, GitIgnore};
use crate::options::stdin::FilesInput;
use crate::output::{details, grid_details, Mode, View};
use crate::output::{Mode, View, details, grid_details};
use crate::theme::Options as ThemeOptions;
mod dir_action;
+1 -1
View File
@@ -6,7 +6,7 @@
// SPDX-License-Identifier: MIT
use std::ffi::OsString;
use clap::{arg, builder::PossibleValue, value_parser, Error, ValueEnum};
use clap::{Error, ValueEnum, arg, builder::PossibleValue, value_parser};
use crate::{
fs::filter::{SortCase, SortField},
+1 -1
View File
@@ -6,8 +6,8 @@
// SPDX-License-Identifier: MIT
use clap::ArgMatches;
use crate::options::vars::EZA_STDIN_SEPARATOR;
use crate::options::Vars;
use crate::options::vars::EZA_STDIN_SEPARATOR;
use std::ffi::OsString;
use std::io;
use std::io::IsTerminal;
+5 -5
View File
@@ -10,7 +10,8 @@ use crate::output::TerminalWidth::Automatic;
use crate::fs::feature::xattr;
use crate::options::parser::ColorScaleModeArgs;
use crate::options::{vars, NumberSource, OptionsError, Vars};
use crate::options::{NumberSource, OptionsError, Vars, vars};
use crate::output::TerminalWidth::Set;
use crate::output::color_scale::{ColorScaleMode, ColorScaleOptions};
use crate::output::file_name::Options as FileStyle;
use crate::output::grid_details::{self, RowThreshold};
@@ -18,8 +19,7 @@ use crate::output::table::{
Columns, FlagsFormat, GroupFormat, Options as TableOptions, SizeFormat, TimeTypes, UserFormat,
};
use crate::output::time::TimeFormat;
use crate::output::TerminalWidth::Set;
use crate::output::{details, grid, Mode, TerminalWidth, View};
use crate::output::{Mode, TerminalWidth, View, details, grid};
use super::parser::{ColorScaleArgs, TimeArgs};
@@ -353,8 +353,8 @@ impl TimeFormat {
"full-iso" => return Ok(TimeFormat::FullISO),
"relative" => return Ok(TimeFormat::Relative),
s if !s.starts_with('+') => {
let error_middle =
format!("{}{}",
let error_middle = format!(
"{}{}",
"Please start the format with a plus sign (+) to indicate a custom format.\n",
"For example: \"+%Y-%m-%d %H:%M:%S\"",
);
+1 -1
View File
@@ -9,7 +9,7 @@ use nu_ansi_term::{Color as Colour, Style};
use palette::{FromColor, LinSrgb, Oklab, Srgb};
use crate::{
fs::{dir_action::RecurseOptions, feature::git::GitCache, fields::Size, DotFilter, File},
fs::{DotFilter, File, dir_action::RecurseOptions, feature::git::GitCache, fields::Size},
output::{table::TimeType, tree::TreeDepth},
};
+13 -13
View File
@@ -295,22 +295,22 @@ impl<'a> Render<'a> {
let mut dir = None;
let follow_links = self.opts.follow_links;
if let Some(r) = self.recurse {
if (if follow_links {
if let Some(r) = self.recurse
&& (if follow_links {
file.points_to_directory()
} else {
file.is_directory()
}) && r.tree
&& !r.is_too_deep(depth.0)
{
trace!("matching on read_dir");
match file.read_dir() {
Ok(d) => {
dir = Some(d);
}
Err(e) => {
errors.push((e, None));
}
})
&& r.tree
&& !r.is_too_deep(depth.0)
{
trace!("matching on read_dir");
match file.read_dir() {
Ok(d) => {
dir = Some(d);
}
Err(e) => {
errors.push((e, None));
}
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
// SPDX-License-Identifier: MIT
use super::file_name::QuoteStyle;
use nu_ansi_term::{AnsiString as ANSIString, Style};
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
use percent_encoding::{AsciiSet, CONTROLS, utf8_percent_encode};
pub fn escape(
string: String,
+29 -33
View File
@@ -240,10 +240,11 @@ impl<C: Colours> FileName<'_, '_, C> {
bits.push(style.paint(" ".repeat(spaces_count as usize)));
}
if self.file.parent_dir.is_none() && self.options.absolute == Absolute::Off {
if let Some(parent) = self.file.path.parent() {
self.add_parent_bits(&mut bits, parent);
}
if self.file.parent_dir.is_none()
&& self.options.absolute == Absolute::Off
&& let Some(parent) = self.file.path.parent()
{
self.add_parent_bits(&mut bits, parent);
}
if !self.file.name.is_empty() {
@@ -292,10 +293,9 @@ impl<C: Colours> FileName<'_, '_, C> {
bits.push(bit);
}
if should_add_classify_char {
if let Some(class) = self.classify_char(target) {
bits.push(Style::default().paint(class));
}
if should_add_classify_char && let Some(class) = self.classify_char(target)
{
bits.push(Style::default().paint(class));
}
}
}
@@ -318,21 +318,19 @@ impl<C: Colours> FileName<'_, '_, C> {
// Do nothing — the error gets displayed on the next line
}
}
} else if should_add_classify_char {
if let Some(class) = self.classify_char(self.file) {
bits.push(Style::default().paint(class));
}
} else if should_add_classify_char && let Some(class) = self.classify_char(self.file) {
bits.push(Style::default().paint(class));
}
if self.mount_style == MountStyle::MountInfo {
if let Some(mount_details) = self.file.mount_point_info() {
// This is a filesystem mounted on the directory, output its details
bits.push(Style::default().paint(" ["));
bits.push(Style::default().paint(mount_details.source.clone()));
bits.push(Style::default().paint(" ("));
bits.push(Style::default().paint(mount_details.fstype.clone()));
bits.push(Style::default().paint(")]"));
}
if self.mount_style == MountStyle::MountInfo
&& let Some(mount_details) = self.file.mount_point_info()
{
// This is a filesystem mounted on the directory, output its details
bits.push(Style::default().paint(" ["));
bits.push(Style::default().paint(mount_details.source.clone()));
bits.push(Style::default().paint(" ("));
bits.push(Style::default().paint(mount_details.fstype.clone()));
bits.push(Style::default().paint(")]"));
}
bits.into()
@@ -415,16 +413,15 @@ impl<C: Colours> FileName<'_, '_, C> {
let mut bits = Vec::new();
let mut display_hyperlink = false;
if self.options.embed_hyperlinks == EmbedHyperlinks::On {
if let Some(abs_path) = self
if self.options.embed_hyperlinks == EmbedHyperlinks::On
&& let Some(abs_path) = self
.file
.absolute_path()
.and_then(|p| p.as_os_str().to_str())
{
bits.push(ANSIString::from(escape::get_hyperlink_start_tag(abs_path)));
{
bits.push(ANSIString::from(escape::get_hyperlink_start_tag(abs_path)));
display_hyperlink = true;
}
display_hyperlink = true;
}
escape(
@@ -466,12 +463,11 @@ impl<C: Colours> FileName<'_, '_, C> {
/// if there’s nowhere else for that fact to be shown.)
#[must_use]
pub fn style(&self) -> Style {
if let LinkStyle::JustFilenames = self.link_style {
if let Some(ref target) = self.target {
if target.is_broken() {
return self.colours.broken_symlink();
}
}
if let LinkStyle::JustFilenames = self.link_style
&& let Some(ref target) = self.target
&& target.is_broken()
{
return self.colours.broken_symlink();
}
#[rustfmt::skip]
+1 -1
View File
@@ -8,8 +8,8 @@ use std::io::{self, Write};
use term_grid::{Direction, Filling, Grid, GridOptions};
use crate::fs::filter::FileFilter;
use crate::fs::File;
use crate::fs::filter::FileFilter;
use crate::output::file_name::Options as FileStyle;
use crate::theme::Theme;
+28 -28
View File
@@ -190,35 +190,35 @@ impl<'a> Render<'a> {
// via the `EZA_GRID_ROWS` environment variable
// and the grid is going to get rendered with fewer rows,
// then render a details list view instead.
if let RowThreshold::MinimumRows(minimum_rows) = self.row_threshold {
if grid.row_count() < minimum_rows {
let Self {
dir,
files,
theme,
file_style,
details: opts,
filter,
git_ignoring,
git,
git_repos,
..
} = self;
if let RowThreshold::MinimumRows(minimum_rows) = self.row_threshold
&& grid.row_count() < minimum_rows
{
let Self {
dir,
files,
theme,
file_style,
details: opts,
filter,
git_ignoring,
git,
git_repos,
..
} = self;
let r = DetailsRender {
dir,
files,
theme,
file_style,
opts,
recurse: None,
filter,
git_ignoring,
git,
git_repos,
};
return r.render(w);
}
let r = DetailsRender {
dir,
files,
theme,
file_style,
opts,
recurse: None,
filter,
git_ignoring,
git,
git_repos,
};
return r.render(w);
}
if self.details.header {
+1 -1
View File
@@ -5,7 +5,7 @@
// SPDX-FileCopyrightText: 2014 Benjamin Sago
// SPDX-License-Identifier: MIT
use nu_ansi_term::Style;
use phf::{phf_map, Map};
use phf::{Map, phf_map};
use crate::fs::File;
+1 -1
View File
@@ -8,8 +8,8 @@ use std::io::{self, Write};
use nu_ansi_term::AnsiStrings as ANSIStrings;
use crate::fs::filter::FileFilter;
use crate::fs::File;
use crate::fs::filter::FileFilter;
use crate::output::cell::TextCellContents;
use crate::output::file_name::Options as FileStyle;
use crate::theme::Theme;
+2 -2
View File
@@ -15,12 +15,12 @@ use crate::output::cell::TextCell;
use crate::output::table::FlagsFormat;
#[cfg(not(target_os = "netbsd"))]
extern "C" {
unsafe extern "C" {
fn fflagstostr(flags: libc::c_ulong) -> *const libc::c_char;
}
#[cfg(target_os = "netbsd")]
extern "C" {
unsafe extern "C" {
fn flags_to_string(flags: libc::c_ulong, def: *const libc::c_char) -> *const libc::c_char;
}
+1 -1
View File
@@ -5,8 +5,8 @@
// SPDX-FileCopyrightText: 2014 Benjamin Sago
// SPDX-License-Identifier: MIT
use crate::fs::fields as f;
use crate::output::table::FlagsFormat;
use crate::output::TextCell;
use crate::output::table::FlagsFormat;
use nu_ansi_term::Style;
// See https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+11 -14
View File
@@ -45,12 +45,11 @@ impl Render for Option<f::Group> {
};
let current_uid = users.get_current_uid();
if let Some(current_user) = users.get_user_by_uid(current_uid) {
if current_user.primary_group_id() == group.gid()
|| group.members().iter().any(|u| u == current_user.name())
{
style = colours.yours();
}
if let Some(current_user) = users.get_user_by_uid(current_uid)
&& (current_user.primary_group_id() == group.gid()
|| group.members().iter().any(|u| u == current_user.name()))
{
style = colours.yours();
}
if group.gid() == 0 && style != colours.yours() {
@@ -62,14 +61,12 @@ impl Render for Option<f::Group> {
UserFormat::Numeric => group.gid().to_string(),
};
if let GroupFormat::Smart = group_format {
if let Some(file_uid) = file_user {
if let Some(file_user) = users.get_user_by_uid(file_uid.0) {
if file_user.name().to_string_lossy() == group.name().to_string_lossy() {
group_name = ":".to_string();
}
}
}
if let GroupFormat::Smart = group_format
&& let Some(file_uid) = file_user
&& let Some(file_user) = users.get_user_by_uid(file_uid.0)
&& file_user.name().to_string_lossy() == group.name().to_string_lossy()
{
group_name = ":".to_string();
}
TextCell::paint(style, group_name)
+1 -1
View File
@@ -57,8 +57,8 @@ pub mod test {
use nu_ansi_term::Color::*;
use nu_ansi_term::Style;
use uzers::mock::MockUsers;
use uzers::User;
use uzers::mock::MockUsers;
struct TestColours;
+2 -2
View File
@@ -17,9 +17,9 @@ use std::sync::LazyLock;
use uzers::UsersCache;
use crate::fs::feature::git::GitCache;
use crate::fs::{fields as f, File};
use crate::options::vars::EZA_WINDOWS_ATTRIBUTES;
use crate::fs::{File, fields as f};
use crate::options::Vars;
use crate::options::vars::EZA_WINDOWS_ATTRIBUTES;
use crate::output::cell::TextCell;
use crate::output::color_scale::ColorScaleInformation;
#[cfg(unix)]
+23 -21
View File
@@ -172,26 +172,28 @@ mod test {
#[test]
fn short_month_width_hindi() {
let max_month_width = 4;
assert!([
"\u{091C}\u{0928}\u{0970}", // जन॰
"\u{092B}\u{093C}\u{0930}\u{0970}", // फ़र॰
"\u{092E}\u{093E}\u{0930}\u{094D}\u{091A}", // मार्च
"\u{0905}\u{092A}\u{094D}\u{0930}\u{0948}\u{0932}", // अप्रैल
"\u{092E}\u{0908}", // मई
"\u{091C}\u{0942}\u{0928}", // जून
"\u{091C}\u{0941}\u{0932}\u{0970}", // जुल॰
"\u{0905}\u{0917}\u{0970}", // अग॰
"\u{0938}\u{093F}\u{0924}\u{0970}", // सित॰
"\u{0905}\u{0915}\u{094D}\u{0924}\u{0942}\u{0970}", // अक्तू॰
"\u{0928}\u{0935}\u{0970}", // नव॰
"\u{0926}\u{093F}\u{0938}\u{0970}", // दिस॰
]
.iter()
.map(|month| format!(
"{:<width$}",
month,
width = short_month_padding(max_month_width, month)
))
.all(|string| UnicodeWidthStr::width(string.as_str()) == max_month_width));
assert!(
[
"\u{091C}\u{0928}\u{0970}", // जन॰
"\u{092B}\u{093C}\u{0930}\u{0970}", // फ़र॰
"\u{092E}\u{093E}\u{0930}\u{094D}\u{091A}", // मार्च
"\u{0905}\u{092A}\u{094D}\u{0930}\u{0948}\u{0932}", // अप्रैल
"\u{092E}\u{0908}", // मई
"\u{091C}\u{0942}\u{0928}", // जून
"\u{091C}\u{0941}\u{0932}\u{0970}", // जुल॰
"\u{0905}\u{0917}\u{0970}", // अग॰
"\u{0938}\u{093F}\u{0924}\u{0970}", // सित॰
"\u{0905}\u{0915}\u{094D}\u{0924}\u{0942}\u{0970}", // अक्तू॰
"\u{0928}\u{0935}\u{0970}", // नव॰
"\u{0926}\u{093F}\u{0938}\u{0970}", // दिस॰
]
.iter()
.map(|month| format!(
"{:<width$}",
month,
width = short_month_padding(max_month_width, month)
))
.all(|string| UnicodeWidthStr::width(string.as_str()) == max_month_width)
);
}
}
+4 -4
View File
@@ -57,10 +57,10 @@ where
match iter.peek() {
Some(&"5") => {
let _ = iter.next();
if let Some(byte) = iter.next() {
if let Ok(num) = byte.parse() {
return Some(Fixed(num));
}
if let Some(byte) = iter.next()
&& let Ok(num) = byte.parse()
{
return Some(Fixed(num));
}
}
+9 -12
View File
@@ -277,10 +277,10 @@ impl FileStyle for ExtensionMappings {
}
}
GlobPattern::Simple(map) => {
if let Some(ext) = maybe_ext {
if let Some(style) = map.get(ext) {
return Some(*style);
}
if let Some(ext) = maybe_ext
&& let Some(style) = map.get(ext)
{
return Some(*style);
}
}
}
@@ -479,19 +479,16 @@ impl FileNameColours for Theme {
}
fn style_override(&self, file: &File<'_>) -> Option<FileNameStyle> {
if let Some(ref name_overrides) = self.ui.filenames {
if let Some(file_override) = name_overrides.get(&file.name) {
if let Some(ref name_overrides) = self.ui.filenames
&& let Some(file_override) = name_overrides.get(&file.name) {
return Some(*file_override);
}
}
if let Some(ref ext_overrides) = self.ui.extensions {
if let Some(ext) = file.ext.clone() {
if let Some(file_override) = ext_overrides.get(&ext) {
if let Some(ref ext_overrides) = self.ui.extensions
&& let Some(ext) = file.ext.clone()
&& let Some(file_override) = ext_overrides.get(&ext) {
return Some(*file_override);
}
}
}
None
}