From 16492171165efd9ade748291a5ae8e1fad7c4921 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Tue, 10 Aug 2021 15:37:57 +0200 Subject: [PATCH 1/4] uucore: remove distinction between common and custom errors As custom errors are prefered over wrapping around common errors, the distinction between UCommonError and UCustomError is removed. This reduces the number of types and makes the error handling easier to understand. --- src/uu/chown/src/chown.rs | 4 +- src/uu/df/src/df.rs | 4 +- src/uu/du/src/du.rs | 4 +- src/uu/false/src/false.rs | 5 +- src/uu/install/src/install.rs | 4 +- src/uu/ln/src/ln.rs | 4 +- src/uu/ls/src/ls.rs | 4 +- src/uu/mktemp/src/mktemp.rs | 4 +- src/uu/sort/src/sort.rs | 4 +- src/uu/touch/src/touch.rs | 2 +- src/uucore/src/lib/mods/error.rs | 297 +++++++------------------------ 11 files changed, 84 insertions(+), 252 deletions(-) diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 53cf61e83..4a9da3f77 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -14,7 +14,7 @@ use uucore::fs::resolve_relative_path; use uucore::libc::{gid_t, uid_t}; use uucore::perms::{wrap_chown, Verbosity}; -use uucore::error::{FromIo, UError, UResult, USimpleError}; +use uucore::error::{FromIo, UResult, USimpleError}; use clap::{crate_version, App, Arg}; @@ -324,7 +324,7 @@ impl Chowner { ret |= self.traverse(f); } if ret != 0 { - return Err(UError::from(ret)); + return Err(ret.into()); } Ok(()) } diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index baa5fe292..cdfdf0b2d 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -8,7 +8,7 @@ #[macro_use] extern crate uucore; -use uucore::error::UCustomError; +use uucore::error::UError; use uucore::error::UResult; #[cfg(unix)] use uucore::fsext::statfs_fn; @@ -274,7 +274,7 @@ impl Display for DfError { impl Error for DfError {} -impl UCustomError for DfError { +impl UError for DfError { fn code(&self) -> i32 { match self { DfError::InvalidBaseValue(_) => 1, diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 9c05eb982..d85cc941c 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -32,7 +32,7 @@ use std::path::PathBuf; use std::str::FromStr; use std::time::{Duration, UNIX_EPOCH}; use std::{error::Error, fmt::Display}; -use uucore::error::{UCustomError, UResult}; +use uucore::error::{UError, UResult}; use uucore::parse_size::{parse_size, ParseSizeError}; use uucore::InvalidEncodingHandling; #[cfg(windows)] @@ -438,7 +438,7 @@ Try '{} --help' for more information.", impl Error for DuError {} -impl UCustomError for DuError { +impl UError for DuError { fn code(&self) -> i32 { match self { Self::InvalidMaxDepthArg(_) => 1, diff --git a/src/uu/false/src/false.rs b/src/uu/false/src/false.rs index 2d64c8376..170788898 100644 --- a/src/uu/false/src/false.rs +++ b/src/uu/false/src/false.rs @@ -9,13 +9,12 @@ extern crate uucore; use clap::App; -use uucore::error::{UError, UResult}; -use uucore::executable; +use uucore::{error::UResult, executable}; #[uucore_procs::gen_uumain] pub fn uumain(args: impl uucore::Args) -> UResult<()> { uu_app().get_matches_from(args); - Err(UError::from(1)) + Err(1.into()) } pub fn uu_app() -> App<'static, 'static> { diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 8ce219f7a..d7b18c895 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -17,7 +17,7 @@ use file_diff::diff; use filetime::{set_file_times, FileTime}; use uucore::backup_control::{self, BackupMode}; use uucore::entries::{grp2gid, usr2uid}; -use uucore::error::{FromIo, UCustomError, UIoError, UResult, USimpleError}; +use uucore::error::{FromIo, UError, UIoError, UResult, USimpleError}; use uucore::perms::{wrap_chgrp, wrap_chown, Verbosity}; use libc::{getegid, geteuid}; @@ -66,7 +66,7 @@ enum InstallError { OmittingDirectory(PathBuf), } -impl UCustomError for InstallError { +impl UError for InstallError { fn code(&self) -> i32 { match self { InstallError::Unimplemented(_) => 2, diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index 65bdcf36c..7010ff5e4 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -11,7 +11,7 @@ extern crate uucore; use clap::{crate_version, App, Arg}; -use uucore::error::{UCustomError, UResult}; +use uucore::error::{UError, UResult}; use std::borrow::Cow; use std::error::Error; @@ -79,7 +79,7 @@ impl Display for LnError { impl Error for LnError {} -impl UCustomError for LnError { +impl UError for LnError { fn code(&self) -> i32 { match self { Self::TargetIsDirectory(_) => 1, diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index ef314dfa8..b8b18bc69 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -39,7 +39,7 @@ use std::{ time::Duration, }; use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; -use uucore::error::{set_exit_code, FromIo, UCustomError, UResult}; +use uucore::error::{set_exit_code, FromIo, UError, UResult}; use unicode_width::UnicodeWidthStr; #[cfg(unix)] @@ -133,7 +133,7 @@ enum LsError { NoMetadata(PathBuf), } -impl UCustomError for LsError { +impl UError for LsError { fn code(&self) -> i32 { match self { LsError::InvalidLineWidth(_) => 2, diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 8a4b472aa..e1dd604a0 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -12,7 +12,7 @@ extern crate uucore; use clap::{crate_version, App, Arg}; -use uucore::error::{FromIo, UCustomError, UResult}; +use uucore::error::{FromIo, UError, UResult}; use std::env; use std::error::Error; @@ -49,7 +49,7 @@ enum MkTempError { InvalidTemplate(String), } -impl UCustomError for MkTempError {} +impl UError for MkTempError {} impl Error for MkTempError {} diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index ae869ba49..3eebe7c4a 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -45,7 +45,7 @@ use std::path::Path; use std::path::PathBuf; use std::str::Utf8Error; use unicode_width::UnicodeWidthStr; -use uucore::error::{set_exit_code, UCustomError, UResult, USimpleError, UUsageError}; +use uucore::error::{set_exit_code, UError, UResult, USimpleError, UUsageError}; use uucore::parse_size::{parse_size, ParseSizeError}; use uucore::version_cmp::version_cmp; use uucore::InvalidEncodingHandling; @@ -164,7 +164,7 @@ enum SortError { impl Error for SortError {} -impl UCustomError for SortError { +impl UError for SortError { fn code(&self) -> i32 { match self { SortError::Disorder { .. } => 1, diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index dd2b05d0e..49efa676a 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -17,7 +17,7 @@ use clap::{crate_version, App, Arg, ArgGroup}; use filetime::*; use std::fs::{self, File}; use std::path::Path; -use uucore::error::{FromIo, UResult, USimpleError}; +use uucore::error::{FromIo, UError, UResult, USimpleError}; static ABOUT: &str = "Update the access and modification times of each FILE to the current time."; pub mod options { diff --git a/src/uucore/src/lib/mods/error.rs b/src/uucore/src/lib/mods/error.rs index c6120672f..fbeea4ed2 100644 --- a/src/uucore/src/lib/mods/error.rs +++ b/src/uucore/src/lib/mods/error.rs @@ -6,11 +6,11 @@ //! This module provides types to reconcile these exit codes with idiomatic Rust error //! handling. This has a couple advantages over manually using [`std::process::exit`]: //! 1. It enables the use of `?`, `map_err`, `unwrap_or`, etc. in `uumain`. -//! 1. It encourages the use of `UResult`/`Result` in functions in the utils. +//! 1. It encourages the use of [`UResult`]/[`Result`] in functions in the utils. //! 1. The error messages are largely standardized across utils. //! 1. Standardized error messages can be created from external result types //! (i.e. [`std::io::Result`] & `clap::ClapResult`). -//! 1. `set_exit_code` takes away the burden of manually tracking exit codes for non-fatal errors. +//! 1. [`set_exit_code`] takes away the burden of manually tracking exit codes for non-fatal errors. //! //! # Usage //! The signature of a typical util should be: @@ -19,7 +19,7 @@ //! ... //! } //! ``` -//! [`UResult`] is a simple wrapper around [`Result`] with a custom error type: [`UError`]. The +//! [`UResult`] is a simple wrapper around [`Result`] with a custom error trait: [`UError`]. The //! most important difference with types implementing [`std::error::Error`] is that [`UError`]s //! can specify the exit code of the program when they are returned from `uumain`: //! * When `Ok` is returned, the code set with [`set_exit_code`] is used as exit code. If @@ -41,8 +41,8 @@ //! [`set_exit_code`]. See the documentation on that function for more information. //! //! # Guidelines -//! * Use common errors where possible. -//! * Add variants to [`UCommonError`] if an error appears in multiple utils. +//! * Use error types from `uucore` where possible. +//! * Add error types to `uucore` if an error appears in multiple utils. //! * Prefer proper custom error types over [`ExitCode`] and [`USimpleError`]. //! * [`USimpleError`] may be used in small utils with simple error handling. //! * Using [`ExitCode`] is not recommended but can be useful for converting utils to use @@ -87,115 +87,10 @@ pub fn set_exit_code(code: i32) { EXIT_CODE.store(code, Ordering::SeqCst); } -/// Should be returned by all utils. -/// -/// Two additional methods are implemented on [`UResult`] on top of the normal [`Result`] methods: -/// `map_err_code` & `map_err_code_message`. -/// -/// These methods are used to convert [`UCommonError`]s into errors with a custom error code and -/// message. -pub type UResult = Result; +/// Result type that should be returned by all utils. +pub type UResult = Result>; -trait UResultTrait { - fn map_err_code(self, mapper: fn(&UCommonError) -> Option) -> Self; - fn map_err_code_and_message(self, mapper: fn(&UCommonError) -> Option<(i32, String)>) -> Self; -} - -impl UResultTrait for UResult { - fn map_err_code(self, mapper: fn(&UCommonError) -> Option) -> Self { - if let Err(UError::Common(error)) = self { - if let Some(code) = mapper(&error) { - Err(UCommonErrorWithCode { code, error }.into()) - } else { - Err(error.into()) - } - } else { - self - } - } - - fn map_err_code_and_message(self, mapper: fn(&UCommonError) -> Option<(i32, String)>) -> Self { - if let Err(UError::Common(ref error)) = self { - if let Some((code, message)) = mapper(error) { - return Err(USimpleError { code, message }.into()); - } - } - self - } -} - -/// The error type of [`UResult`]. -/// -/// `UError::Common` errors are defined in [`uucore`](crate) while `UError::Custom` errors are -/// defined by the utils. -/// ``` -/// use uucore::error::USimpleError; -/// let err = USimpleError::new(1, "Error!!".into()); -/// assert_eq!(1, err.code()); -/// assert_eq!(String::from("Error!!"), format!("{}", err)); -/// ``` -pub enum UError { - Common(UCommonError), - Custom(Box), -} - -impl UError { - /// The error code of [`UResult`] - /// - /// This function defines the error code associated with an instance of - /// [`UResult`]. To associate error codes for self-defined instances of - /// `UResult::Custom` (i.e. [`UCustomError`]), implement the - /// [`code`-function there](UCustomError::code). - pub fn code(&self) -> i32 { - match self { - UError::Common(e) => e.code(), - UError::Custom(e) => e.code(), - } - } - - /// Whether to print usage help for a [`UResult`] - /// - /// Defines if a variant of [`UResult`] should print a short usage message - /// below the error. The usage message is printed when this function returns - /// `true`. To do this for self-defined instances of `UResult::Custom` (i.e. - /// [`UCustomError`]), implement the [`usage`-function - /// there](UCustomError::usage). - pub fn usage(&self) -> bool { - match self { - UError::Common(e) => e.usage(), - UError::Custom(e) => e.usage(), - } - } -} - -impl From for UError { - fn from(v: UCommonError) -> Self { - UError::Common(v) - } -} - -impl From for UError { - fn from(v: i32) -> Self { - UError::Custom(Box::new(ExitCode(v))) - } -} - -impl From for UError { - fn from(v: E) -> Self { - UError::Custom(Box::new(v) as Box) - } -} - -impl Display for UError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - UError::Common(e) => e.fmt(f), - UError::Custom(e) => e.fmt(f), - } - } -} - -/// Custom errors defined by the utils. +/// Custom errors defined by the utils and `uucore`. /// /// All errors should implement [`std::error::Error`], [`std::fmt::Display`] and /// [`std::fmt::Debug`] and have an additional `code` method that specifies the @@ -204,7 +99,7 @@ impl Display for UError { /// An example of a custom error from `ls`: /// /// ``` -/// use uucore::error::{UCustomError, UResult}; +/// use uucore::error::{UError, UResult}; /// use std::{ /// error::Error, /// fmt::{Display, Debug}, @@ -217,7 +112,7 @@ impl Display for UError { /// NoMetadata(PathBuf), /// } /// -/// impl UCustomError for LsError { +/// impl UError for LsError { /// fn code(&self) -> i32 { /// match self { /// LsError::InvalidLineWidth(_) => 2, @@ -248,12 +143,12 @@ impl Display for UError { /// } /// ``` /// -/// The call to `into()` is required to convert the [`UCustomError`] to an -/// instance of [`UError`]. +/// The call to `into()` is required to convert the `LsError` to +/// [`Box`]. The implementation for `From` is provided automatically. /// /// A crate like [`quick_error`](https://crates.io/crates/quick-error) might /// also be used, but will still require an `impl` for the `code` method. -pub trait UCustomError: Error + Send { +pub trait UError: Error + Send { /// Error code of a custom error. /// /// Set a return value for each variant of an enum-type to associate an @@ -263,7 +158,7 @@ pub trait UCustomError: Error + Send { /// # Example /// /// ``` - /// use uucore::error::{UCustomError}; + /// use uucore::error::{UError}; /// use std::{ /// error::Error, /// fmt::{Display, Debug}, @@ -277,7 +172,7 @@ pub trait UCustomError: Error + Send { /// Bing(), /// } /// - /// impl UCustomError for MyError { + /// impl UError for MyError { /// fn code(&self) -> i32 { /// match self { /// MyError::Foo(_) => 2, @@ -314,7 +209,7 @@ pub trait UCustomError: Error + Send { /// # Example /// /// ``` - /// use uucore::error::{UCustomError}; + /// use uucore::error::{UError}; /// use std::{ /// error::Error, /// fmt::{Display, Debug}, @@ -328,7 +223,7 @@ pub trait UCustomError: Error + Send { /// Bing(), /// } /// - /// impl UCustomError for MyError { + /// impl UError for MyError { /// fn usage(&self) -> bool { /// match self { /// // This will have a short usage help appended @@ -357,41 +252,17 @@ pub trait UCustomError: Error + Send { } } -impl From> for i32 { - fn from(e: Box) -> i32 { - e.code() +impl From for Box +where + T: UError + 'static, +{ + fn from(t: T) -> Box { + Box::new(t) } } -/// A [`UCommonError`] with an overridden exit code. +/// A simple error type with an exit code and a message that implements [`UError`]. /// -/// This exit code is returned instead of the default exit code for the [`UCommonError`]. This is -/// typically created with the either the `UResult::map_err_code` or `UCommonError::with_code` -/// method. -#[derive(Debug)] -pub struct UCommonErrorWithCode { - code: i32, - error: UCommonError, -} - -impl Error for UCommonErrorWithCode {} - -impl Display for UCommonErrorWithCode { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - self.error.fmt(f) - } -} - -impl UCustomError for UCommonErrorWithCode { - fn code(&self) -> i32 { - self.code - } -} - -/// A simple error type with an exit code and a message that implements [`UCustomError`]. -/// -/// It is typically created with the `UResult::map_err_code_and_message` method. Alternatively, it -/// can be constructed by manually: /// ``` /// use uucore::error::{UResult, USimpleError}; /// let err = USimpleError { code: 1, message: "error!".into()}; @@ -407,8 +278,8 @@ pub struct USimpleError { impl USimpleError { #[allow(clippy::new_ret_no_self)] - pub fn new(code: i32, message: String) -> UError { - UError::Custom(Box::new(Self { code, message })) + pub fn new(code: i32, message: String) -> Box { + Box::new(Self { code, message }) } } @@ -420,7 +291,7 @@ impl Display for USimpleError { } } -impl UCustomError for USimpleError { +impl UError for USimpleError { fn code(&self) -> i32 { self.code } @@ -434,8 +305,8 @@ pub struct UUsageError { impl UUsageError { #[allow(clippy::new_ret_no_self)] - pub fn new(code: i32, message: String) -> UError { - UError::Custom(Box::new(Self { code, message })) + pub fn new(code: i32, message: String) -> Box { + Box::new(Self { code, message }) } } @@ -447,7 +318,7 @@ impl Display for UUsageError { } } -impl UCustomError for UUsageError { +impl UError for UUsageError { fn code(&self) -> i32 { self.code } @@ -465,13 +336,13 @@ impl UCustomError for UUsageError { /// There are two ways to construct this type: with [`UIoError::new`] or by calling the /// [`FromIo::map_err_context`] method on a [`std::io::Result`] or [`std::io::Error`]. /// ``` -/// use uucore::error::{FromIo, UResult, UIoError, UCommonError}; +/// use uucore::error::{FromIo, UResult, UIoError, UError}; /// use std::fs::File; /// use std::path::Path; /// let path = Path::new("test.txt"); /// /// // Manual construction -/// let e: UIoError = UIoError::new( +/// let e: Box = UIoError::new( /// std::io::ErrorKind::NotFound, /// format!("cannot access '{}'", path.display()) /// ); @@ -487,18 +358,21 @@ pub struct UIoError { } impl UIoError { - pub fn new(kind: std::io::ErrorKind, context: String) -> Self { - Self { + #[allow(clippy::new_ret_no_self)] + pub fn new(kind: std::io::ErrorKind, context: String) -> Box { + Box::new(Self { context, inner: std::io::Error::new(kind, ""), - } + }) } +} - pub fn code(&self) -> i32 { +impl UError for UIoError { + fn code(&self) -> i32 { 1 } - pub fn usage(&self) -> bool { + fn usage(&self) -> bool { false } } @@ -537,46 +411,33 @@ impl Display for UIoError { } } -/// Enables the conversion from `std::io::Error` to `UError` and from `std::io::Result` to -/// `UResult`. +/// Enables the conversion from [`std::io::Error`] to [`UError`] and from [`std::io::Result`] to +/// [`UResult`]. pub trait FromIo { fn map_err_context(self, context: impl FnOnce() -> String) -> T; } -impl FromIo for std::io::Error { - fn map_err_context(self, context: impl FnOnce() -> String) -> UIoError { - UIoError { +impl FromIo> for std::io::Error { + fn map_err_context(self, context: impl FnOnce() -> String) -> Box { + Box::new(UIoError { context: (context)(), inner: self, - } + }) } } impl FromIo> for std::io::Result { fn map_err_context(self, context: impl FnOnce() -> String) -> UResult { - self.map_err(|e| UError::Common(UCommonError::Io(e.map_err_context(context)))) + self.map_err(|e| e.map_err_context(context) as Box) } } -impl FromIo for std::io::ErrorKind { - fn map_err_context(self, context: impl FnOnce() -> String) -> UIoError { - UIoError { +impl FromIo> for std::io::ErrorKind { + fn map_err_context(self, context: impl FnOnce() -> String) -> Box { + Box::new(UIoError { context: (context)(), inner: std::io::Error::new(self, ""), - } - } -} - -impl From for UCommonError { - fn from(e: UIoError) -> UCommonError { - UCommonError::Io(e) - } -} - -impl From for UError { - fn from(e: UIoError) -> UError { - let common: UCommonError = e.into(); - common.into() + }) } } @@ -647,47 +508,6 @@ macro_rules! uio_error( }) ); -/// Common errors for utilities. -/// -/// If identical errors appear across multiple utilities, they should be added here. -#[derive(Debug)] -pub enum UCommonError { - Io(UIoError), - // Clap(UClapError), -} - -impl UCommonError { - pub fn with_code(self, code: i32) -> UCommonErrorWithCode { - UCommonErrorWithCode { code, error: self } - } - - pub fn code(&self) -> i32 { - 1 - } - - pub fn usage(&self) -> bool { - false - } -} - -impl From for i32 { - fn from(common: UCommonError) -> i32 { - match common { - UCommonError::Io(e) => e.code(), - } - } -} - -impl Error for UCommonError {} - -impl Display for UCommonError { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - match self { - UCommonError::Io(e) => e.fmt(f), - } - } -} - /// A special error type that does not print any message when returned from /// `uumain`. Especially useful for porting utilities to using [`UResult`]. /// @@ -705,6 +525,13 @@ impl Display for UCommonError { #[derive(Debug)] pub struct ExitCode(pub i32); +impl ExitCode { + #[allow(clippy::new_ret_no_self)] + pub fn new(code: i32) -> Box { + Box::new(Self(code)) + } +} + impl Error for ExitCode {} impl Display for ExitCode { @@ -713,8 +540,14 @@ impl Display for ExitCode { } } -impl UCustomError for ExitCode { +impl UError for ExitCode { fn code(&self) -> i32 { self.0 } } + +impl From for Box { + fn from(i: i32) -> Self { + ExitCode::new(i) + } +} From d12d4f760c09a75b6c4ea12dd180a1bfb92aba38 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Tue, 10 Aug 2021 16:50:42 +0200 Subject: [PATCH 2/4] uucore: {USimpleError, UUsageError}::new take Into instead of String --- src/uu/chown/src/chown.rs | 2 +- src/uu/dirname/src/dirname.rs | 2 +- src/uu/id/src/id.rs | 8 ++++---- src/uu/sort/src/sort.rs | 4 ++-- src/uucore/src/lib/mods/error.rs | 14 +++++++------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 4a9da3f77..3d882a564 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -109,7 +109,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if derefer == 1 { return Err(USimpleError::new( 1, - "-R --dereference requires -H or -L".to_string(), + "-R --dereference requires -H or -L", )); } derefer = 0; diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index 63ee57272..e7dcc2195 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -79,7 +79,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { print!("{}", separator); } } else { - return Err(UUsageError::new(1, "missing operand".to_string())); + return Err(UUsageError::new(1, "missing operand")); } Ok(()) diff --git a/src/uu/id/src/id.rs b/src/uu/id/src/id.rs index 1dd1b176d..b067be42c 100644 --- a/src/uu/id/src/id.rs +++ b/src/uu/id/src/id.rs @@ -173,20 +173,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if (state.nflag || state.rflag) && default_format && !state.cflag { return Err(USimpleError::new( 1, - "cannot print only names or real IDs in default format".to_string(), + "cannot print only names or real IDs in default format", )); } if state.zflag && default_format && !state.cflag { // NOTE: GNU test suite "id/zero.sh" needs this stderr output: return Err(USimpleError::new( 1, - "option --zero not permitted in default format".to_string(), + "option --zero not permitted in default format", )); } if state.user_specified && state.cflag { return Err(USimpleError::new( 1, - "cannot print security context when user specified".to_string(), + "cannot print security context when user specified", )); } @@ -220,7 +220,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } else { return Err(USimpleError::new( 1, - "--context (-Z) works only on an SELinux-enabled kernel".to_string(), + "--context (-Z) works only on an SELinux-enabled kernel", )); } } diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 3eebe7c4a..e0b445782 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -1238,7 +1238,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if separator.len() != 1 { return Err(UUsageError::new( 2, - "separator must be exactly one character long".into(), + "separator must be exactly one character long", )); } settings.separator = Some(separator.chars().next().unwrap()) @@ -1517,7 +1517,7 @@ fn exec( file_merger.write_all(settings, output) } else if settings.check { if files.len() > 1 { - Err(UUsageError::new(2, "only one file allowed with -c".into())) + Err(UUsageError::new(2, "only one file allowed with -c")) } else { check::check(files.first().unwrap(), settings) } diff --git a/src/uucore/src/lib/mods/error.rs b/src/uucore/src/lib/mods/error.rs index fbeea4ed2..caccb6ac0 100644 --- a/src/uucore/src/lib/mods/error.rs +++ b/src/uucore/src/lib/mods/error.rs @@ -268,7 +268,7 @@ where /// let err = USimpleError { code: 1, message: "error!".into()}; /// let res: UResult<()> = Err(err.into()); /// // or using the `new` method: -/// let res: UResult<()> = Err(USimpleError::new(1, "error!".into())); +/// let res: UResult<()> = Err(USimpleError::new(1, "error!")); /// ``` #[derive(Debug)] pub struct USimpleError { @@ -278,8 +278,8 @@ pub struct USimpleError { impl USimpleError { #[allow(clippy::new_ret_no_self)] - pub fn new(code: i32, message: String) -> Box { - Box::new(Self { code, message }) + pub fn new>(code: i32, message: S) -> Box { + Box::new(Self { code, message: message.into() }) } } @@ -305,8 +305,8 @@ pub struct UUsageError { impl UUsageError { #[allow(clippy::new_ret_no_self)] - pub fn new(code: i32, message: String) -> Box { - Box::new(Self { code, message }) + pub fn new>(code: i32, message: S) -> Box { + Box::new(Self { code, message: message.into() }) } } @@ -359,9 +359,9 @@ pub struct UIoError { impl UIoError { #[allow(clippy::new_ret_no_self)] - pub fn new(kind: std::io::ErrorKind, context: String) -> Box { + pub fn new>(kind: std::io::ErrorKind, context: S) -> Box { Box::new(Self { - context, + context: context.into(), inner: std::io::Error::new(kind, ""), }) } From ea3c15f0dd815d76cb084cdd59e5fec3cc6e95d2 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Tue, 10 Aug 2021 17:00:16 +0200 Subject: [PATCH 3/4] uucore: use default UError impl for UIoError --- src/uucore/src/lib/mods/error.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/uucore/src/lib/mods/error.rs b/src/uucore/src/lib/mods/error.rs index caccb6ac0..c22b434c4 100644 --- a/src/uucore/src/lib/mods/error.rs +++ b/src/uucore/src/lib/mods/error.rs @@ -367,15 +367,7 @@ impl UIoError { } } -impl UError for UIoError { - fn code(&self) -> i32 { - 1 - } - - fn usage(&self) -> bool { - false - } -} +impl UError for UIoError {} impl Error for UIoError {} From 14459cf611baf2d4d2c87dfbadb1837ea069434d Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Tue, 10 Aug 2021 17:56:41 +0200 Subject: [PATCH 4/4] rustfmt --- src/uu/chown/src/chown.rs | 5 +---- src/uucore/src/lib/mods/error.rs | 10 ++++++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 3d882a564..7df263c5d 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -107,10 +107,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if recursive { if bit_flag == FTS_PHYSICAL { if derefer == 1 { - return Err(USimpleError::new( - 1, - "-R --dereference requires -H or -L", - )); + return Err(USimpleError::new(1, "-R --dereference requires -H or -L")); } derefer = 0; } diff --git a/src/uucore/src/lib/mods/error.rs b/src/uucore/src/lib/mods/error.rs index c22b434c4..664fc9841 100644 --- a/src/uucore/src/lib/mods/error.rs +++ b/src/uucore/src/lib/mods/error.rs @@ -279,7 +279,10 @@ pub struct USimpleError { impl USimpleError { #[allow(clippy::new_ret_no_self)] pub fn new>(code: i32, message: S) -> Box { - Box::new(Self { code, message: message.into() }) + Box::new(Self { + code, + message: message.into(), + }) } } @@ -306,7 +309,10 @@ pub struct UUsageError { impl UUsageError { #[allow(clippy::new_ret_no_self)] pub fn new>(code: i32, message: S) -> Box { - Box::new(Self { code, message: message.into() }) + Box::new(Self { + code, + message: message.into(), + }) } }