1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 20:17:45 +00:00

ls: move to thiserror

This commit is contained in:
Sylvestre Ledru 2025-03-21 17:18:40 +01:00 committed by Dorian Péron
parent 9d123febb3
commit 305be09403
2 changed files with 38 additions and 105 deletions

View file

@ -26,6 +26,7 @@ lscolors = { workspace = true }
number_prefix = { workspace = true }
selinux = { workspace = true, optional = true }
terminal_size = { workspace = true }
thiserror = { workspace = true }
uucore = { workspace = true, features = [
"colors",
"custom-tz-fmt",

View file

@ -10,9 +10,8 @@ use std::os::windows::fs::MetadataExt;
use std::{cell::OnceCell, num::IntErrorKind};
use std::{
cmp::Reverse,
error::Error,
ffi::{OsStr, OsString},
fmt::{Display, Write as FmtWrite},
fmt::Write as FmtWrite,
fs::{self, DirEntry, FileType, Metadata, ReadDir},
io::{stdout, BufWriter, ErrorKind, Stdout, Write},
path::{Path, PathBuf},
@ -35,7 +34,7 @@ use clap::{
use glob::{MatchOptions, Pattern};
use lscolors::LsColors;
use term_grid::{Direction, Filling, Grid, GridOptions};
use thiserror::Error;
use uucore::error::USimpleError;
use uucore::format::human::{human_readable, SizeFormat};
#[cfg(all(unix, not(any(target_os = "android", target_os = "macos"))))]
@ -175,14 +174,41 @@ const POSIXLY_CORRECT_BLOCK_SIZE: u64 = 512;
const DEFAULT_BLOCK_SIZE: u64 = 1024;
const DEFAULT_FILE_SIZE_BLOCK_SIZE: u64 = 1;
#[derive(Debug)]
#[derive(Error, Debug)]
enum LsError {
#[error("invalid line width: '{0}'")]
InvalidLineWidth(String),
IOError(std::io::Error),
IOErrorContext(std::io::Error, PathBuf, bool),
#[error("general io error: {0}")]
IOError(#[from] std::io::Error),
#[error("{}", match .1.kind() {
ErrorKind::NotFound => format!("cannot access '{}': No such file or directory", .0.to_string_lossy()),
ErrorKind::PermissionDenied => match .1.raw_os_error().unwrap_or(1) {
1 => format!("cannot access '{}': Operation not permitted", .0.to_string_lossy()),
_ => if .0.is_dir() {
format!("cannot open directory '{}': Permission denied", .0.to_string_lossy())
} else {
format!("cannot open file '{}': Permission denied", .0.to_string_lossy())
},
},
_ => match .1.raw_os_error().unwrap_or(1) {
9 => format!("cannot open directory '{}': Bad file descriptor", .0.to_string_lossy()),
_ => format!("unknown io error: '{:?}', '{:?}'", .0.to_string_lossy(), .1),
},
})]
IOErrorContext(PathBuf, std::io::Error, bool),
#[error("invalid --block-size argument '{0}'")]
BlockSizeParseError(String),
#[error("--dired and --zero are incompatible")]
DiredAndZeroAreIncompatible,
#[error("{}: not listing already-listed directory", .0.to_string_lossy())]
AlreadyListedError(PathBuf),
#[error("invalid --time-style argument {0}\nPossible values are: {1:?}\n\nFor more information try --help")]
TimeStyleParseError(String, Vec<String>),
}
@ -201,100 +227,6 @@ impl UError for LsError {
}
}
impl Error for LsError {}
impl Display for LsError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BlockSizeParseError(s) => {
write!(f, "invalid --block-size argument {}", s.quote())
}
Self::DiredAndZeroAreIncompatible => {
write!(f, "--dired and --zero are incompatible")
}
Self::TimeStyleParseError(s, possible_time_styles) => {
write!(
f,
"invalid --time-style argument {}\nPossible values are: {:?}\n\nFor more information try --help",
s.quote(),
possible_time_styles
)
}
Self::InvalidLineWidth(s) => write!(f, "invalid line width: {}", s.quote()),
Self::IOError(e) => write!(f, "general io error: {e}"),
Self::IOErrorContext(e, p, _) => {
let error_kind = e.kind();
let errno = e.raw_os_error().unwrap_or(1i32);
match error_kind {
// No such file or directory
ErrorKind::NotFound => {
write!(
f,
"cannot access '{}': No such file or directory",
p.to_string_lossy(),
)
}
// Permission denied and Operation not permitted
ErrorKind::PermissionDenied =>
{
#[allow(clippy::wildcard_in_or_patterns)]
match errno {
1i32 => {
write!(
f,
"cannot access '{}': Operation not permitted",
p.to_string_lossy(),
)
}
13i32 | _ => {
if p.is_dir() {
write!(
f,
"cannot open directory '{}': Permission denied",
p.to_string_lossy(),
)
} else {
write!(
f,
"cannot open file '{}': Permission denied",
p.to_string_lossy(),
)
}
}
}
}
_ => match errno {
9i32 => {
// only should ever occur on a read_dir on a bad fd
write!(
f,
"cannot open directory '{}': Bad file descriptor",
p.to_string_lossy(),
)
}
_ => {
write!(
f,
"unknown io error: '{:?}', '{:?}'",
p.to_string_lossy(),
e
)
}
},
}
}
Self::AlreadyListedError(path) => {
write!(
f,
"{}: not listing already-listed directory",
path.to_string_lossy()
)
}
}
}
}
#[derive(PartialEq, Eq, Debug)]
pub enum Format {
Columns,
@ -2054,8 +1986,8 @@ impl PathData {
}
}
show!(LsError::IOErrorContext(
err,
self.p_buf.clone(),
err,
self.command_line
));
None
@ -2161,8 +2093,8 @@ pub fn list(locs: Vec<&Path>, config: &Config) -> UResult<()> {
// flush stdout buffer before the error to preserve formatting and order
out.flush()?;
show!(LsError::IOErrorContext(
err,
path_data.p_buf.clone(),
err,
path_data.command_line
));
continue;
@ -2396,8 +2328,8 @@ fn enter_directory(
Err(err) => {
out.flush()?;
show!(LsError::IOErrorContext(
err,
e.p_buf.clone(),
err,
e.command_line
));
continue;
@ -3365,7 +3297,7 @@ fn display_item_name(
}
}
Err(err) => {
show!(LsError::IOErrorContext(err, path.p_buf.clone(), false));
show!(LsError::IOErrorContext(path.p_buf.clone(), err, false));
}
}
}
@ -3448,7 +3380,7 @@ fn get_security_context(config: &Config, p_buf: &Path, must_dereference: bool) -
Err(err) => {
// The Path couldn't be dereferenced, so return early and set exit code 1
// to indicate a minor error
show!(LsError::IOErrorContext(err, p_buf.to_path_buf(), false));
show!(LsError::IOErrorContext(p_buf.to_path_buf(), err, false));
return substitute_string;
}
Ok(_md) => (),