mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
head: refactor to use specific error enums
This commit is contained in:
parent
2cdf30938d
commit
5fe6706c51
3 changed files with 53 additions and 24 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2770,6 +2770,7 @@ version = "0.0.28"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
"thiserror 2.0.9",
|
||||||
"uucore",
|
"uucore",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ path = "src/head.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
memchr = { workspace = true }
|
memchr = { workspace = true }
|
||||||
|
thiserror = { workspace = true }
|
||||||
uucore = { workspace = true, features = ["ringbuffer", "lines", "fs"] }
|
uucore = { workspace = true, features = ["ringbuffer", "lines", "fs"] }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
use clap::{crate_version, Arg, ArgAction, ArgMatches, Command};
|
use clap::{crate_version, Arg, ArgAction, ArgMatches, Command};
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::io::{self, BufWriter, ErrorKind, Read, Seek, SeekFrom, Write};
|
use std::io::{self, BufWriter, ErrorKind, Read, Seek, SeekFrom, Write};
|
||||||
|
use std::num::TryFromIntError;
|
||||||
|
use thiserror::Error;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{FromIo, UResult, USimpleError};
|
use uucore::error::{FromIo, UError, UResult};
|
||||||
use uucore::line_ending::LineEnding;
|
use uucore::line_ending::LineEnding;
|
||||||
use uucore::lines::lines;
|
use uucore::lines::lines;
|
||||||
use uucore::{format_usage, help_about, help_usage, show};
|
use uucore::{format_usage, help_about, help_usage, show};
|
||||||
|
@ -37,6 +39,36 @@ mod take;
|
||||||
use take::take_all_but;
|
use take::take_all_but;
|
||||||
use take::take_lines;
|
use take::take_lines;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
enum HeadError {
|
||||||
|
/// Wrapper around `io::Error`
|
||||||
|
#[error("error reading {name}: {err}")]
|
||||||
|
Io { name: String, err: io::Error },
|
||||||
|
|
||||||
|
#[error("parse error: {0}")]
|
||||||
|
ParseError(String),
|
||||||
|
|
||||||
|
#[error("bad argument encoding")]
|
||||||
|
BadEncoding,
|
||||||
|
|
||||||
|
#[error("{0}: number of -bytes or -lines is too large")]
|
||||||
|
NumTooLarge(#[from] TryFromIntError),
|
||||||
|
|
||||||
|
#[error("clap error: {0}")]
|
||||||
|
Clap(#[from] clap::Error),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
MatchOption(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UError for HeadError {
|
||||||
|
fn code(&self) -> i32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HeadResult<T> = Result<T, HeadError>;
|
||||||
|
|
||||||
pub fn uu_app() -> Command {
|
pub fn uu_app() -> Command {
|
||||||
Command::new(uucore::util_name())
|
Command::new(uucore::util_name())
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
|
@ -152,7 +184,7 @@ impl Mode {
|
||||||
|
|
||||||
fn arg_iterate<'a>(
|
fn arg_iterate<'a>(
|
||||||
mut args: impl uucore::Args + 'a,
|
mut args: impl uucore::Args + 'a,
|
||||||
) -> UResult<Box<dyn Iterator<Item = OsString> + 'a>> {
|
) -> HeadResult<Box<dyn Iterator<Item = OsString> + 'a>> {
|
||||||
// argv[0] is always present
|
// argv[0] is always present
|
||||||
let first = args.next().unwrap();
|
let first = args.next().unwrap();
|
||||||
if let Some(second) = args.next() {
|
if let Some(second) = args.next() {
|
||||||
|
@ -160,22 +192,19 @@ fn arg_iterate<'a>(
|
||||||
match parse::parse_obsolete(s) {
|
match parse::parse_obsolete(s) {
|
||||||
Some(Ok(iter)) => Ok(Box::new(vec![first].into_iter().chain(iter).chain(args))),
|
Some(Ok(iter)) => Ok(Box::new(vec![first].into_iter().chain(iter).chain(args))),
|
||||||
Some(Err(e)) => match e {
|
Some(Err(e)) => match e {
|
||||||
parse::ParseError::Syntax => Err(USimpleError::new(
|
parse::ParseError::Syntax => Err(HeadError::ParseError(format!(
|
||||||
1,
|
"bad argument format: {}",
|
||||||
format!("bad argument format: {}", s.quote()),
|
s.quote()
|
||||||
)),
|
))),
|
||||||
parse::ParseError::Overflow => Err(USimpleError::new(
|
parse::ParseError::Overflow => Err(HeadError::ParseError(format!(
|
||||||
1,
|
|
||||||
format!(
|
|
||||||
"invalid argument: {} Value too large for defined datatype",
|
"invalid argument: {} Value too large for defined datatype",
|
||||||
s.quote()
|
s.quote()
|
||||||
),
|
))),
|
||||||
)),
|
|
||||||
},
|
},
|
||||||
None => Ok(Box::new(vec![first, second].into_iter().chain(args))),
|
None => Ok(Box::new(vec![first, second].into_iter().chain(args))),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(USimpleError::new(1, "bad argument encoding".to_owned()))
|
Err(HeadError::BadEncoding)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(Box::new(vec![first].into_iter()))
|
Ok(Box::new(vec![first].into_iter()))
|
||||||
|
@ -247,10 +276,7 @@ fn catch_too_large_numbers_in_backwards_bytes_or_lines(n: u64) -> Option<usize>
|
||||||
match usize::try_from(n) {
|
match usize::try_from(n) {
|
||||||
Ok(value) => Some(value),
|
Ok(value) => Some(value),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
show!(USimpleError::new(
|
show!(HeadError::NumTooLarge(e));
|
||||||
1,
|
|
||||||
format!("{e}: number of -bytes or -lines is too large")
|
|
||||||
));
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,16 +537,17 @@ fn uu_head(options: &HeadOptions) -> UResult<()> {
|
||||||
head_file(&mut file, options)
|
head_file(&mut file, options)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if res.is_err() {
|
if let Err(e) = res {
|
||||||
let name = if file.as_str() == "-" {
|
let name = if file.as_str() == "-" {
|
||||||
"standard input"
|
"standard input"
|
||||||
} else {
|
} else {
|
||||||
file
|
file
|
||||||
};
|
};
|
||||||
show!(USimpleError::new(
|
return Err(HeadError::Io {
|
||||||
1,
|
name: name.to_string(),
|
||||||
format!("error reading {name}: Input/output error")
|
err: e,
|
||||||
));
|
}
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
@ -537,7 +564,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = match HeadOptions::get_from(&matches) {
|
let args = match HeadOptions::get_from(&matches) {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
Err(s) => {
|
Err(s) => {
|
||||||
return Err(USimpleError::new(1, s));
|
return Err(HeadError::MatchOption(s).into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
uu_head(&args)
|
uu_head(&args)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue