mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
base32: Moved clap argument parsing to base32.rs
Now, all base_common.rs has is the handle_input function.
This commit is contained in:
parent
d56462a4b3
commit
11d0565f0e
2 changed files with 124 additions and 122 deletions
|
@ -10,6 +10,12 @@ extern crate uucore;
|
||||||
use uucore::encoding::Format;
|
use uucore::encoding::Format;
|
||||||
use uucore::InvalidEncodingHandling;
|
use uucore::InvalidEncodingHandling;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{stdin, BufReader};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use clap::{App, Arg};
|
||||||
|
|
||||||
mod base_common;
|
mod base_common;
|
||||||
|
|
||||||
static SUMMARY: &str = "Base32 encode or decode FILE, or standard input, to standard output.";
|
static SUMMARY: &str = "Base32 encode or decode FILE, or standard input, to standard output.";
|
||||||
|
@ -22,13 +28,68 @@ static LONG_HELP: &str = "
|
||||||
to attempt to recover from any other non-alphabet bytes in the
|
to attempt to recover from any other non-alphabet bytes in the
|
||||||
encoded stream.
|
encoded stream.
|
||||||
";
|
";
|
||||||
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
fn get_usage() -> String {
|
fn get_usage() -> String {
|
||||||
format!("{0} [OPTION]... [FILE]", executable!())
|
format!("{0} [OPTION]... [FILE]", executable!())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod options {
|
||||||
|
pub static DECODE: &str = "decode";
|
||||||
|
pub static WRAP: &str = "wrap";
|
||||||
|
pub static IGNORE_GARBAGE: &str = "ignore-garbage";
|
||||||
|
pub static FILE: &str = "file";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
decode: bool,
|
||||||
|
ignore_garbage: bool,
|
||||||
|
wrap_cols: Option<usize>,
|
||||||
|
to_read: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
fn from(options: clap::ArgMatches) -> Config {
|
||||||
|
let file: Option<String> = match options.values_of(options::FILE) {
|
||||||
|
Some(mut values) => {
|
||||||
|
let name = values.next().unwrap();
|
||||||
|
if values.len() != 0 {
|
||||||
|
crash!(3, "extra operand ‘{}’", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if name == "-" {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
if !Path::exists(Path::new(name)) {
|
||||||
|
crash!(2, "{}: No such file or directory", name);
|
||||||
|
}
|
||||||
|
Some(name.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cols = match options.value_of(options::WRAP) {
|
||||||
|
Some(num) => match num.parse::<usize>() {
|
||||||
|
Ok(n) => Some(n),
|
||||||
|
Err(e) => {
|
||||||
|
crash!(1, "invalid wrap size: ‘{}’: {}", num, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Config {
|
||||||
|
decode: options.is_present(options::DECODE),
|
||||||
|
ignore_garbage: options.is_present(options::IGNORE_GARBAGE),
|
||||||
|
wrap_cols: cols,
|
||||||
|
to_read: file,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
base_common::execute(
|
execute(
|
||||||
args.collect_str(InvalidEncodingHandling::ConvertLossy)
|
args.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
.accept_any(),
|
.accept_any(),
|
||||||
SUMMARY,
|
SUMMARY,
|
||||||
|
@ -37,3 +98,63 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
Format::Base32,
|
Format::Base32,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn execute(args: Vec<String>, _summary: &str, long_help: &str, usage: &str, format: Format) -> i32 {
|
||||||
|
let app = App::new(executable!())
|
||||||
|
.version(VERSION)
|
||||||
|
.usage(usage)
|
||||||
|
.about(long_help)
|
||||||
|
// Format arguments.
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::DECODE)
|
||||||
|
.short("d")
|
||||||
|
.long(options::DECODE)
|
||||||
|
.help("decode data"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::IGNORE_GARBAGE)
|
||||||
|
.short("i")
|
||||||
|
.long(options::IGNORE_GARBAGE)
|
||||||
|
.help("when decoding, ignore non-alphabetic characters"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::WRAP)
|
||||||
|
.short("w")
|
||||||
|
.long(options::WRAP)
|
||||||
|
.takes_value(true)
|
||||||
|
.help(
|
||||||
|
"wrap encoded lines after COLS character (default 76, 0 to disable wrapping)",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// "multiple" arguments are used to check whether there is more than one
|
||||||
|
// file passed in.
|
||||||
|
.arg(Arg::with_name(options::FILE).index(1).multiple(true));
|
||||||
|
|
||||||
|
let config: Config = Config::from(app.get_matches_from(args));
|
||||||
|
match config.to_read {
|
||||||
|
// Read from file.
|
||||||
|
Some(name) => {
|
||||||
|
let file_buf = safe_unwrap!(File::open(Path::new(&name)));
|
||||||
|
let mut input = BufReader::new(file_buf);
|
||||||
|
base_common::handle_input(
|
||||||
|
&mut input,
|
||||||
|
format,
|
||||||
|
config.wrap_cols,
|
||||||
|
config.ignore_garbage,
|
||||||
|
config.decode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// stdin
|
||||||
|
None => {
|
||||||
|
base_common::handle_input(
|
||||||
|
&mut stdin().lock(),
|
||||||
|
format,
|
||||||
|
config.wrap_cols,
|
||||||
|
config.ignore_garbage,
|
||||||
|
config.decode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
|
@ -7,130 +7,11 @@
|
||||||
// For the full copyright and license information, please view the LICENSE file
|
// For the full copyright and license information, please view the LICENSE file
|
||||||
// that was distributed with this source code.
|
// that was distributed with this source code.
|
||||||
|
|
||||||
use std::fs::File;
|
use std::io::{stdout, Read, Write};
|
||||||
use std::io::{stdin, stdout, BufReader, Read, Write};
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use clap::{App, Arg};
|
|
||||||
use uucore::encoding::{wrap_print, Data, Format};
|
use uucore::encoding::{wrap_print, Data, Format};
|
||||||
|
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub fn handle_input<R: Read>(
|
||||||
|
|
||||||
pub mod options {
|
|
||||||
pub static DECODE: &str = "decode";
|
|
||||||
pub static WRAP: &str = "wrap";
|
|
||||||
pub static IGNORE_GARBAGE: &str = "ignore-garbage";
|
|
||||||
pub static FILE: &str = "file";
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Config {
|
|
||||||
decode: bool,
|
|
||||||
ignore_garbage: bool,
|
|
||||||
wrap_cols: Option<usize>,
|
|
||||||
to_read: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
fn from(options: clap::ArgMatches) -> Config {
|
|
||||||
let file: Option<String> = match options.values_of(options::FILE) {
|
|
||||||
Some(mut values) => {
|
|
||||||
let name = values.next().unwrap();
|
|
||||||
if values.len() != 0 {
|
|
||||||
crash!(3, "extra operand ‘{}’", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == "-" {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
if !Path::exists(Path::new(name)) {
|
|
||||||
crash!(2, "{}: No such file or directory", name);
|
|
||||||
}
|
|
||||||
Some(name.to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let cols = match options.value_of(options::WRAP) {
|
|
||||||
Some(num) => match num.parse::<usize>() {
|
|
||||||
Ok(n) => Some(n),
|
|
||||||
Err(e) => {
|
|
||||||
crash!(1, "invalid wrap size: ‘{}’: {}", num, e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Config {
|
|
||||||
decode: options.is_present(options::DECODE),
|
|
||||||
ignore_garbage: options.is_present(options::IGNORE_GARBAGE),
|
|
||||||
wrap_cols: cols,
|
|
||||||
to_read: file,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn execute(args: Vec<String>, _summary: &str, long_help: &str, usage: &str, format: Format) -> i32 {
|
|
||||||
let app = App::new(executable!())
|
|
||||||
.version(VERSION)
|
|
||||||
.usage(usage)
|
|
||||||
.about(long_help)
|
|
||||||
// Format arguments.
|
|
||||||
.arg(
|
|
||||||
Arg::with_name(options::DECODE)
|
|
||||||
.short("d")
|
|
||||||
.long(options::DECODE)
|
|
||||||
.help("decode data"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name(options::IGNORE_GARBAGE)
|
|
||||||
.short("i")
|
|
||||||
.long(options::IGNORE_GARBAGE)
|
|
||||||
.help("when decoding, ignore non-alphabetic characters"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name(options::WRAP)
|
|
||||||
.short("w")
|
|
||||||
.long(options::WRAP)
|
|
||||||
.takes_value(true)
|
|
||||||
.help(
|
|
||||||
"wrap encoded lines after COLS character (default 76, 0 to disable wrapping)",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
// "multiple" arguments are used to check whether there is more than one
|
|
||||||
// file passed in.
|
|
||||||
.arg(Arg::with_name(options::FILE).index(1).multiple(true));
|
|
||||||
|
|
||||||
let config: Config = Config::from(app.get_matches_from(args));
|
|
||||||
match config.to_read {
|
|
||||||
// Read from file.
|
|
||||||
Some(name) => {
|
|
||||||
let file_buf = safe_unwrap!(File::open(Path::new(&name)));
|
|
||||||
let mut input = BufReader::new(file_buf);
|
|
||||||
handle_input(
|
|
||||||
&mut input,
|
|
||||||
format,
|
|
||||||
config.wrap_cols,
|
|
||||||
config.ignore_garbage,
|
|
||||||
config.decode,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// stdin
|
|
||||||
None => {
|
|
||||||
handle_input(
|
|
||||||
&mut stdin().lock(),
|
|
||||||
format,
|
|
||||||
config.wrap_cols,
|
|
||||||
config.ignore_garbage,
|
|
||||||
config.decode,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_input<R: Read>(
|
|
||||||
input: &mut R,
|
input: &mut R,
|
||||||
format: Format,
|
format: Format,
|
||||||
line_wrap: Option<usize>,
|
line_wrap: Option<usize>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue