1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-30 04:27:45 +00:00

base32: base_common use UResult

This commit is contained in:
Thomas Queiroz 2021-10-02 23:10:00 -03:00
parent b2fa51ddd9
commit 9dd401c358
No known key found for this signature in database
GPG key ID: 229D2DDF7ECA5F8F

View file

@ -11,13 +11,16 @@ use std::io::{stdout, Read, Write};
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::encoding::{wrap_print, Data, Format}; use uucore::encoding::{wrap_print, Data, Format};
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::InvalidEncodingHandling; use uucore::InvalidEncodingHandling;
use std::fs::File; use std::fs::File;
use std::io::{BufReader, Stdin}; use std::io::{BufReader, Stdin};
use std::path::Path; use std::path::Path;
use clap::{App, Arg}; use clap::{crate_version, App, Arg};
pub static BASE_CMD_PARSE_ERROR: i32 = 1;
// Config. // Config.
pub struct Config { pub struct Config {
@ -35,15 +38,14 @@ pub mod options {
} }
impl Config { impl Config {
pub fn from(app_name: &str, options: &clap::ArgMatches) -> Result<Config, String> { pub fn from(options: &clap::ArgMatches) -> UResult<Config> {
let file: Option<String> = match options.values_of(options::FILE) { let file: Option<String> = match options.values_of(options::FILE) {
Some(mut values) => { Some(mut values) => {
let name = values.next().unwrap(); let name = values.next().unwrap();
if let Some(extra_op) = values.next() { if let Some(extra_op) = values.next() {
return Err(format!( return Err(UUsageError::new(
"extra operand {}\nTry '{} --help' for more information.", BASE_CMD_PARSE_ERROR,
extra_op.quote(), format!("extra operand {}", extra_op.quote(),),
app_name
)); ));
} }
@ -51,7 +53,10 @@ impl Config {
None None
} else { } else {
if !Path::exists(Path::new(name)) { if !Path::exists(Path::new(name)) {
return Err(format!("{}: No such file or directory", name.maybe_quote())); return Err(USimpleError::new(
BASE_CMD_PARSE_ERROR,
format!("{}: No such file or directory", name.maybe_quote()),
));
} }
Some(name.to_owned()) Some(name.to_owned())
} }
@ -62,8 +67,12 @@ impl Config {
let cols = options let cols = options
.value_of(options::WRAP) .value_of(options::WRAP)
.map(|num| { .map(|num| {
num.parse::<usize>() num.parse::<usize>().map_err(|_| {
.map_err(|_| format!("invalid wrap size: {}", num.quote())) USimpleError::new(
BASE_CMD_PARSE_ERROR,
format!("invalid wrap size: {}", num.quote()),
)
})
}) })
.transpose()?; .transpose()?;
@ -76,23 +85,17 @@ impl Config {
} }
} }
pub fn parse_base_cmd_args( pub fn parse_base_cmd_args(args: impl uucore::Args, about: &str, usage: &str) -> UResult<Config> {
args: impl uucore::Args, let app = base_app(about).usage(usage);
name: &str,
version: &str,
about: &str,
usage: &str,
) -> Result<Config, String> {
let app = base_app(name, version, about).usage(usage);
let arg_list = args let arg_list = args
.collect_str(InvalidEncodingHandling::ConvertLossy) .collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any(); .accept_any();
Config::from(name, &app.get_matches_from(arg_list)) Config::from(&app.get_matches_from(arg_list))
} }
pub fn base_app<'a>(name: &str, version: &'a str, about: &'a str) -> App<'static, 'a> { pub fn base_app<'a>(about: &'a str) -> App<'static, 'a> {
App::new(name) App::new(uucore::util_name())
.version(version) .version(crate_version!())
.about(about) .about(about)
// Format arguments. // Format arguments.
.arg( .arg(
@ -121,14 +124,15 @@ pub fn base_app<'a>(name: &str, version: &'a str, about: &'a str) -> App<'static
.arg(Arg::with_name(options::FILE).index(1).multiple(true)) .arg(Arg::with_name(options::FILE).index(1).multiple(true))
} }
pub fn get_input<'a>(config: &Config, stdin_ref: &'a Stdin) -> Box<dyn Read + 'a> { pub fn get_input<'a>(config: &Config, stdin_ref: &'a Stdin) -> UResult<Box<dyn Read + 'a>> {
match &config.to_read { match &config.to_read {
Some(name) => { Some(name) => {
let file_buf = crash_if_err!(1, File::open(Path::new(name))); let file_buf =
Box::new(BufReader::new(file_buf)) // as Box<dyn Read> File::open(Path::new(name)).map_err_context(|| name.maybe_quote().to_string())?;
Ok(Box::new(BufReader::new(file_buf))) // as Box<dyn Read>
} }
None => { None => {
Box::new(stdin_ref.lock()) // as Box<dyn Read> Ok(Box::new(stdin_ref.lock())) // as Box<dyn Read>
} }
} }
} }
@ -139,8 +143,7 @@ pub fn handle_input<R: Read>(
line_wrap: Option<usize>, line_wrap: Option<usize>,
ignore_garbage: bool, ignore_garbage: bool,
decode: bool, decode: bool,
name: &str, ) -> UResult<()> {
) {
let mut data = Data::new(input, format).ignore_garbage(ignore_garbage); let mut data = Data::new(input, format).ignore_garbage(ignore_garbage);
if let Some(wrap) = line_wrap { if let Some(wrap) = line_wrap {
data = data.line_wrap(wrap); data = data.line_wrap(wrap);
@ -150,28 +153,23 @@ pub fn handle_input<R: Read>(
match data.encode() { match data.encode() {
Ok(s) => { Ok(s) => {
wrap_print(&data, s); wrap_print(&data, s);
Ok(())
} }
Err(_) => { Err(_) => Err(USimpleError::new(
eprintln!( 1,
"{}: error: invalid input (length must be multiple of 4 characters)", "error: invalid input (length must be multiple of 4 characters)",
name )),
);
exit!(1)
}
} }
} else { } else {
match data.decode() { match data.decode() {
Ok(s) => { Ok(s) => {
if stdout().write_all(&s).is_err() { if stdout().write_all(&s).is_err() {
// on windows console, writing invalid utf8 returns an error // on windows console, writing invalid utf8 returns an error
eprintln!("{}: error: Cannot write non-utf8 data", name); return Err(USimpleError::new(1, "error: cannot write non-utf8 data"));
exit!(1)
} }
Ok(())
} }
Err(_) => { Err(_) => Err(USimpleError::new(1, "error: invalid input")),
eprintln!("{}: error: invalid input", name);
exit!(1)
}
} }
} }
} }