Skip to content

Commit 1ee8092

Browse files
authored
Merge pull request #7525 from sylvestre/thiserror4
Move more programs to thiserror
2 parents 36231f7 + ffe8762 commit 1ee8092

File tree

9 files changed

+109
-210
lines changed

9 files changed

+109
-210
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/install/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ clap = { workspace = true }
2121
filetime = { workspace = true }
2222
file_diff = { workspace = true }
2323
libc = { workspace = true }
24+
thiserror = { workspace = true }
2425
uucore = { workspace = true, features = [
2526
"backup-control",
2627
"buf-copy",

src/uu/install/src/install.rs

Lines changed: 40 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@ mod mode;
1010
use clap::{Arg, ArgAction, ArgMatches, Command};
1111
use file_diff::diff;
1212
use filetime::{set_file_times, FileTime};
13-
use std::error::Error;
14-
use std::fmt::{Debug, Display};
13+
use std::fmt::Debug;
1514
use std::fs::File;
1615
use std::fs::{self, metadata};
1716
use std::path::{Path, PathBuf, MAIN_SEPARATOR};
1817
use std::process;
18+
use thiserror::Error;
1919
use uucore::backup_control::{self, BackupMode};
2020
use uucore::buf_copy::copy_stream;
2121
use uucore::display::Quotable;
2222
use uucore::entries::{grp2gid, usr2uid};
23-
use uucore::error::{FromIo, UError, UIoError, UResult, UUsageError};
23+
use uucore::error::{FromIo, UError, UResult, UUsageError};
2424
use uucore::fs::dir_strip_dot_for_creation;
2525
use uucore::mode::get_umask;
2626
use uucore::perms::{wrap_chown, Verbosity, VerbosityLevel};
2727
use uucore::process::{getegid, geteuid};
28-
use uucore::{format_usage, help_about, help_usage, show, show_error, show_if_err, uio_error};
28+
use uucore::{format_usage, help_about, help_usage, show, show_error, show_if_err};
2929

3030
#[cfg(unix)]
3131
use std::os::unix::fs::{FileTypeExt, MetadataExt};
@@ -52,22 +52,51 @@ pub struct Behavior {
5252
target_dir: Option<String>,
5353
}
5454

55-
#[derive(Debug)]
55+
#[derive(Error, Debug)]
5656
enum InstallError {
57+
#[error("Unimplemented feature: {0}")]
5758
Unimplemented(String),
58-
DirNeedsArg(),
59-
CreateDirFailed(PathBuf, std::io::Error),
59+
60+
#[error("{} with -d requires at least one argument.", uucore::util_name())]
61+
DirNeedsArg,
62+
63+
#[error("failed to create {0}")]
64+
CreateDirFailed(PathBuf, #[source] std::io::Error),
65+
66+
#[error("failed to chmod {}", .0.quote())]
6067
ChmodFailed(PathBuf),
68+
69+
#[error("failed to chown {}: {}", .0.quote(), .1)]
6170
ChownFailed(PathBuf, String),
71+
72+
#[error("invalid target {}: No such file or directory", .0.quote())]
6273
InvalidTarget(PathBuf),
74+
75+
#[error("target {} is not a directory", .0.quote())]
6376
TargetDirIsntDir(PathBuf),
64-
BackupFailed(PathBuf, PathBuf, std::io::Error),
65-
InstallFailed(PathBuf, PathBuf, std::io::Error),
77+
78+
#[error("cannot backup {0} to {1}")]
79+
BackupFailed(PathBuf, PathBuf, #[source] std::io::Error),
80+
81+
#[error("cannot install {0} to {1}")]
82+
InstallFailed(PathBuf, PathBuf, #[source] std::io::Error),
83+
84+
#[error("strip program failed: {0}")]
6685
StripProgramFailed(String),
67-
MetadataFailed(std::io::Error),
86+
87+
#[error("metadata error")]
88+
MetadataFailed(#[source] std::io::Error),
89+
90+
#[error("invalid user: {}", .0.quote())]
6891
InvalidUser(String),
92+
93+
#[error("invalid group: {}", .0.quote())]
6994
InvalidGroup(String),
95+
96+
#[error("omitting directory {}", .0.quote())]
7097
OmittingDirectory(PathBuf),
98+
99+
#[error("failed to access {}: Not a directory", .0.quote())]
71100
NotADirectory(PathBuf),
72101
}
73102

@@ -84,52 +113,6 @@ impl UError for InstallError {
84113
}
85114
}
86115

87-
impl Error for InstallError {}
88-
89-
impl Display for InstallError {
90-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91-
match self {
92-
Self::Unimplemented(opt) => write!(f, "Unimplemented feature: {opt}"),
93-
Self::DirNeedsArg() => {
94-
write!(
95-
f,
96-
"{} with -d requires at least one argument.",
97-
uucore::util_name()
98-
)
99-
}
100-
Self::CreateDirFailed(dir, e) => {
101-
Display::fmt(&uio_error!(e, "failed to create {}", dir.quote()), f)
102-
}
103-
Self::ChmodFailed(file) => write!(f, "failed to chmod {}", file.quote()),
104-
Self::ChownFailed(file, msg) => write!(f, "failed to chown {}: {}", file.quote(), msg),
105-
Self::InvalidTarget(target) => write!(
106-
f,
107-
"invalid target {}: No such file or directory",
108-
target.quote()
109-
),
110-
Self::TargetDirIsntDir(target) => {
111-
write!(f, "target {} is not a directory", target.quote())
112-
}
113-
Self::BackupFailed(from, to, e) => Display::fmt(
114-
&uio_error!(e, "cannot backup {} to {}", from.quote(), to.quote()),
115-
f,
116-
),
117-
Self::InstallFailed(from, to, e) => Display::fmt(
118-
&uio_error!(e, "cannot install {} to {}", from.quote(), to.quote()),
119-
f,
120-
),
121-
Self::StripProgramFailed(msg) => write!(f, "strip program failed: {msg}"),
122-
Self::MetadataFailed(e) => Display::fmt(&uio_error!(e, ""), f),
123-
Self::InvalidUser(user) => write!(f, "invalid user: {}", user.quote()),
124-
Self::InvalidGroup(group) => write!(f, "invalid group: {}", group.quote()),
125-
Self::OmittingDirectory(dir) => write!(f, "omitting directory {}", dir.quote()),
126-
Self::NotADirectory(dir) => {
127-
write!(f, "failed to access {}: Not a directory", dir.quote())
128-
}
129-
}
130-
}
131-
}
132-
133116
#[derive(Clone, Eq, PartialEq)]
134117
pub enum MainFunction {
135118
/// Create directories
@@ -456,7 +439,7 @@ fn behavior(matches: &ArgMatches) -> UResult<Behavior> {
456439
///
457440
fn directory(paths: &[String], b: &Behavior) -> UResult<()> {
458441
if paths.is_empty() {
459-
Err(InstallError::DirNeedsArg().into())
442+
Err(InstallError::DirNeedsArg.into())
460443
} else {
461444
for path in paths.iter().map(Path::new) {
462445
// if the path already exist, don't try to create it again

src/uu/join/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ path = "src/join.rs"
2020
clap = { workspace = true }
2121
uucore = { workspace = true }
2222
memchr = { workspace = true }
23+
thiserror = { workspace = true }
2324

2425
[[bin]]
2526
name = "join"

src/uu/join/src/join.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ use clap::builder::ValueParser;
99
use clap::{Arg, ArgAction, Command};
1010
use memchr::{memchr_iter, memmem::Finder, Memchr3};
1111
use std::cmp::Ordering;
12-
use std::error::Error;
1312
use std::ffi::OsString;
14-
use std::fmt::Display;
1513
use std::fs::File;
1614
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Split, Stdin, Write};
1715
use std::num::IntErrorKind;
1816
#[cfg(unix)]
1917
use std::os::unix::ffi::OsStrExt;
18+
use thiserror::Error;
2019
use uucore::display::Quotable;
2120
use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError};
2221
use uucore::line_ending::LineEnding;
@@ -25,35 +24,22 @@ use uucore::{format_usage, help_about, help_usage};
2524
const ABOUT: &str = help_about!("join.md");
2625
const USAGE: &str = help_usage!("join.md");
2726

28-
#[derive(Debug)]
27+
#[derive(Debug, Error)]
2928
enum JoinError {
30-
IOError(std::io::Error),
29+
#[error("io error: {0}")]
30+
IOError(#[from] std::io::Error),
31+
32+
#[error("{0}")]
3133
UnorderedInput(String),
3234
}
3335

36+
// If you still need the UError implementation for compatibility:
3437
impl UError for JoinError {
3538
fn code(&self) -> i32 {
3639
1
3740
}
3841
}
3942

40-
impl Error for JoinError {}
41-
42-
impl Display for JoinError {
43-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44-
match self {
45-
Self::IOError(e) => write!(f, "io error: {e}"),
46-
Self::UnorderedInput(e) => f.write_str(e),
47-
}
48-
}
49-
}
50-
51-
impl From<std::io::Error> for JoinError {
52-
fn from(error: std::io::Error) -> Self {
53-
Self::IOError(error)
54-
}
55-
}
56-
5743
#[derive(Copy, Clone, PartialEq)]
5844
enum FileNum {
5945
File1,

src/uu/ln/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ path = "src/ln.rs"
1919
[dependencies]
2020
clap = { workspace = true }
2121
uucore = { workspace = true, features = ["backup-control", "fs"] }
22+
thiserror = { workspace = true }
2223

2324
[[bin]]
2425
name = "ln"

src/uu/ln/src/ln.rs

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, sho
1313

1414
use std::borrow::Cow;
1515
use std::collections::HashSet;
16-
use std::error::Error;
1716
use std::ffi::OsString;
18-
use std::fmt::Display;
1917
use std::fs;
18+
use thiserror::Error;
2019

2120
#[cfg(any(unix, target_os = "redox"))]
2221
use std::os::unix::fs::symlink;
@@ -46,38 +45,25 @@ pub enum OverwriteMode {
4645
Force,
4746
}
4847

49-
#[derive(Debug)]
48+
#[derive(Error, Debug)]
5049
enum LnError {
50+
#[error("target {} is not a directory", _0.quote())]
5151
TargetIsDirectory(PathBuf),
52+
53+
#[error("")]
5254
SomeLinksFailed,
55+
56+
#[error("{} and {} are the same file", _0.quote(), _1.quote())]
5357
SameFile(PathBuf, PathBuf),
58+
59+
#[error("missing destination file operand after {}", _0.quote())]
5460
MissingDestination(PathBuf),
55-
ExtraOperand(OsString),
56-
}
5761

58-
impl Display for LnError {
59-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60-
match self {
61-
Self::TargetIsDirectory(s) => write!(f, "target {} is not a directory", s.quote()),
62-
Self::SameFile(s, d) => {
63-
write!(f, "{} and {} are the same file", s.quote(), d.quote())
64-
}
65-
Self::SomeLinksFailed => Ok(()),
66-
Self::MissingDestination(s) => {
67-
write!(f, "missing destination file operand after {}", s.quote())
68-
}
69-
Self::ExtraOperand(s) => write!(
70-
f,
71-
"extra operand {}\nTry '{} --help' for more information.",
72-
s.quote(),
73-
uucore::execution_phrase()
74-
),
75-
}
76-
}
62+
#[error("extra operand {}\nTry '{} --help' for more information.",
63+
format!("{:?}", _0).trim_matches('"'), _1)]
64+
ExtraOperand(OsString, String),
7765
}
7866

79-
impl Error for LnError {}
80-
8167
impl UError for LnError {
8268
fn code(&self) -> i32 {
8369
1
@@ -284,7 +270,11 @@ fn exec(files: &[PathBuf], settings: &Settings) -> UResult<()> {
284270
return Err(LnError::MissingDestination(files[0].clone()).into());
285271
}
286272
if files.len() > 2 {
287-
return Err(LnError::ExtraOperand(files[2].clone().into()).into());
273+
return Err(LnError::ExtraOperand(
274+
files[2].clone().into(),
275+
uucore::execution_phrase().to_string(),
276+
)
277+
.into());
288278
}
289279
assert!(!files.is_empty());
290280

src/uu/ls/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ lscolors = { workspace = true }
2626
number_prefix = { workspace = true }
2727
selinux = { workspace = true, optional = true }
2828
terminal_size = { workspace = true }
29+
thiserror = { workspace = true }
2930
uucore = { workspace = true, features = [
3031
"colors",
3132
"custom-tz-fmt",

0 commit comments

Comments
 (0)