diff --git a/Cargo.lock b/Cargo.lock index 0299274c2..c86bab4b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3229,6 +3229,7 @@ version = "0.0.30" dependencies = [ "clap", "memchr", + "thiserror 2.0.12", "uucore", ] diff --git a/src/uu/split/Cargo.toml b/src/uu/split/Cargo.toml index 631c455bb..47b200bca 100644 --- a/src/uu/split/Cargo.toml +++ b/src/uu/split/Cargo.toml @@ -20,6 +20,7 @@ path = "src/split.rs" clap = { workspace = true } memchr = { workspace = true } uucore = { workspace = true, features = ["fs"] } +thiserror = { workspace = true } [[bin]] name = "split" diff --git a/src/uu/split/src/filenames.rs b/src/uu/split/src/filenames.rs index d2883a711..52b284a16 100644 --- a/src/uu/split/src/filenames.rs +++ b/src/uu/split/src/filenames.rs @@ -39,8 +39,8 @@ use crate::{ OPT_NUMERIC_SUFFIXES_SHORT, OPT_SUFFIX_LENGTH, }; use clap::ArgMatches; -use std::fmt; use std::path::is_separator; +use thiserror::Error; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError}; @@ -79,31 +79,21 @@ pub struct Suffix { } /// An error when parsing suffix parameters from command-line arguments. +#[derive(Debug, Error)] pub enum SuffixError { /// Invalid suffix length parameter. + #[error("invalid suffix length: {}", .0.quote())] NotParsable(String), /// Suffix contains a directory separator, which is not allowed. + #[error("invalid suffix {}, contains directory separator", .0.quote())] ContainsSeparator(String), /// Suffix is not large enough to split into specified chunks + #[error("the suffix length needs to be at least {0}")] TooSmall(usize), } -impl fmt::Display for SuffixError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::NotParsable(s) => write!(f, "invalid suffix length: {}", s.quote()), - Self::TooSmall(i) => write!(f, "the suffix length needs to be at least {i}"), - Self::ContainsSeparator(s) => write!( - f, - "invalid suffix {}, contains directory separator", - s.quote() - ), - } - } -} - impl Suffix { /// Parse the suffix type, start, length and additional suffix from the command-line arguments /// as well process suffix length auto-widening and auto-width scenarios diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index b453040fb..e7321d533 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -15,11 +15,11 @@ use crate::strategy::{NumberType, Strategy, StrategyError}; use clap::{Arg, ArgAction, ArgMatches, Command, ValueHint, parser::ValueSource}; use std::env; use std::ffi::OsString; -use std::fmt; use std::fs::{File, metadata}; use std::io; use std::io::{BufRead, BufReader, BufWriter, ErrorKind, Read, Seek, SeekFrom, Write, stdin}; use std::path::Path; +use thiserror::Error; use uucore::display::Quotable; use uucore::error::{FromIo, UIoError, UResult, USimpleError, UUsageError}; use uucore::parse_size::parse_size_u64; @@ -411,31 +411,39 @@ struct Settings { io_blksize: Option, } +#[derive(Debug, Error)] /// An error when parsing settings from command-line arguments. enum SettingsError { /// Invalid chunking strategy. + #[error("{0}")] Strategy(StrategyError), /// Invalid suffix length parameter. + #[error("{0}")] Suffix(SuffixError), /// Multi-character (Invalid) separator + #[error("multi-character separator {}", .0.quote())] MultiCharacterSeparator(String), /// Multiple different separator characters + #[error("multiple separator characters specified")] MultipleSeparatorCharacters, /// Using `--filter` with `--number` option sub-strategies that print Kth chunk out of N chunks to stdout /// K/N /// l/K/N /// r/K/N + #[error("--filter does not process a chunk extracted to stdout")] FilterWithKthChunkNumber, /// Invalid IO block size + #[error("invalid IO block size: {}", .0.quote())] InvalidIOBlockSize(String), /// The `--filter` option is not supported on Windows. #[cfg(windows)] + #[error("{OPT_FILTER} is currently not supported in this platform")] NotSupported, } @@ -450,30 +458,6 @@ impl SettingsError { } } -impl fmt::Display for SettingsError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Strategy(e) => e.fmt(f), - Self::Suffix(e) => e.fmt(f), - Self::MultiCharacterSeparator(s) => { - write!(f, "multi-character separator {}", s.quote()) - } - Self::MultipleSeparatorCharacters => { - write!(f, "multiple separator characters specified") - } - Self::FilterWithKthChunkNumber => { - write!(f, "--filter does not process a chunk extracted to stdout") - } - Self::InvalidIOBlockSize(s) => write!(f, "invalid IO block size: {}", s.quote()), - #[cfg(windows)] - Self::NotSupported => write!( - f, - "{OPT_FILTER} is currently not supported in this platform" - ), - } - } -} - impl Settings { /// Parse a strategy from the command-line arguments. fn from(matches: &ArgMatches, obs_lines: &Option) -> Result { diff --git a/src/uu/split/src/strategy.rs b/src/uu/split/src/strategy.rs index f8f50b094..7c0d182a1 100644 --- a/src/uu/split/src/strategy.rs +++ b/src/uu/split/src/strategy.rs @@ -7,7 +7,7 @@ use crate::{OPT_BYTES, OPT_LINE_BYTES, OPT_LINES, OPT_NUMBER}; use clap::{ArgMatches, parser::ValueSource}; -use std::fmt; +use thiserror::Error; use uucore::{ display::Quotable, parse_size::{ParseSizeError, parse_size_u64, parse_size_u64_max}, @@ -54,7 +54,7 @@ impl NumberType { } /// An error due to an invalid parameter to the `-n` command-line option. -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Error)] pub enum NumberTypeError { /// The number of chunks was invalid. /// @@ -69,6 +69,7 @@ pub enum NumberTypeError { /// -n r/N /// -n r/K/N /// ``` + #[error("invalid number of chunks: {}", .0.quote())] NumberOfChunks(String), /// The chunk number was invalid. @@ -83,6 +84,7 @@ pub enum NumberTypeError { /// -n l/K/N /// -n r/K/N /// ``` + #[error("invalid chunk number: {}", .0.quote())] ChunkNumber(String), } @@ -191,36 +193,25 @@ pub enum Strategy { } /// An error when parsing a chunking strategy from command-line arguments. +#[derive(Debug, Error)] pub enum StrategyError { /// Invalid number of lines. + #[error("invalid number of lines: {0}")] Lines(ParseSizeError), /// Invalid number of bytes. + #[error("invalid number of bytes: {0}")] Bytes(ParseSizeError), /// Invalid number type. + #[error("{0}")] NumberType(NumberTypeError), /// Multiple chunking strategies were specified (but only one should be). + #[error("cannot split in more than one way")] MultipleWays, } -impl fmt::Display for StrategyError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Lines(e) => write!(f, "invalid number of lines: {e}"), - Self::Bytes(e) => write!(f, "invalid number of bytes: {e}"), - Self::NumberType(NumberTypeError::NumberOfChunks(s)) => { - write!(f, "invalid number of chunks: {}", s.quote()) - } - Self::NumberType(NumberTypeError::ChunkNumber(s)) => { - write!(f, "invalid chunk number: {}", s.quote()) - } - Self::MultipleWays => write!(f, "cannot split in more than one way"), - } - } -} - impl Strategy { /// Parse a strategy from the command-line arguments. pub fn from(matches: &ArgMatches, obs_lines: &Option) -> Result {