mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #2137 from ricardoaiglesias/base64-clap
base64: Moved argument parsing to clap.
This commit is contained in:
commit
038025899d
9 changed files with 238 additions and 239 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1688,6 +1688,8 @@ dependencies = [
|
||||||
name = "uu_base64"
|
name = "uu_base64"
|
||||||
version = "0.0.6"
|
version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"uu_base32",
|
||||||
"uucore",
|
"uucore",
|
||||||
"uucore_procs",
|
"uucore_procs",
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,19 +7,14 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
|
use std::io::{stdin, Read};
|
||||||
|
|
||||||
use uucore::encoding::Format;
|
use uucore::encoding::Format;
|
||||||
use uucore::InvalidEncodingHandling;
|
|
||||||
|
|
||||||
use std::fs::File;
|
pub mod base_common;
|
||||||
use std::io::{stdin, BufReader};
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use clap::{App, Arg};
|
static ABOUT: &str = "
|
||||||
|
|
||||||
mod base_common;
|
|
||||||
|
|
||||||
static SUMMARY: &str = "Base32 encode or decode FILE, or standard input, to standard output.";
|
|
||||||
static LONG_HELP: &str = "
|
|
||||||
With no FILE, or when FILE is -, read standard input.
|
With no FILE, or when FILE is -, read standard input.
|
||||||
|
|
||||||
The data are encoded as described for the base32 alphabet in RFC
|
The data are encoded as described for the base32 alphabet in RFC
|
||||||
|
@ -30,126 +25,41 @@ static LONG_HELP: &str = "
|
||||||
";
|
";
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
static BASE_CMD_PARSE_ERROR: i32 = 1;
|
||||||
|
|
||||||
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 {
|
||||||
let format = Format::Base32;
|
let format = Format::Base32;
|
||||||
let usage = get_usage();
|
let usage = get_usage();
|
||||||
let app = App::new(executable!())
|
let name = executable!();
|
||||||
.version(VERSION)
|
|
||||||
.about(SUMMARY)
|
|
||||||
.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 arg_list = args
|
let config_result: Result<base_common::Config, String> =
|
||||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
base_common::parse_base_cmd_args(args, name, VERSION, ABOUT, &usage);
|
||||||
.accept_any();
|
|
||||||
let config: Config = Config::from(app.get_matches_from(arg_list));
|
if config_result.is_err() {
|
||||||
match config.to_read {
|
match config_result {
|
||||||
// Read from file.
|
Ok(_) => panic!(),
|
||||||
Some(name) => {
|
Err(s) => crash!(BASE_CMD_PARSE_ERROR, "{}", s),
|
||||||
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(
|
// Create a reference to stdin so we can return a locked stdin from
|
||||||
&mut stdin().lock(),
|
// parse_base_cmd_args
|
||||||
format,
|
let stdin_raw = stdin();
|
||||||
config.wrap_cols,
|
let config = config_result.unwrap();
|
||||||
config.ignore_garbage,
|
let mut input: Box<dyn Read> = base_common::get_input(&config, &stdin_raw);
|
||||||
config.decode,
|
|
||||||
);
|
base_common::handle_input(
|
||||||
}
|
&mut input,
|
||||||
};
|
format,
|
||||||
|
config.wrap_cols,
|
||||||
|
config.ignore_garbage,
|
||||||
|
config.decode,
|
||||||
|
name,
|
||||||
|
);
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,122 @@
|
||||||
use std::io::{stdout, Read, Write};
|
use std::io::{stdout, Read, Write};
|
||||||
|
|
||||||
use uucore::encoding::{wrap_print, Data, Format};
|
use uucore::encoding::{wrap_print, Data, Format};
|
||||||
|
use uucore::InvalidEncodingHandling;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufReader, Stdin};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use clap::{App, Arg};
|
||||||
|
|
||||||
|
// Config.
|
||||||
|
pub struct Config {
|
||||||
|
pub decode: bool,
|
||||||
|
pub ignore_garbage: bool,
|
||||||
|
pub wrap_cols: Option<usize>,
|
||||||
|
pub to_read: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
fn from(options: clap::ArgMatches) -> Result<Config, String> {
|
||||||
|
let file: Option<String> = match options.values_of(options::FILE) {
|
||||||
|
Some(mut values) => {
|
||||||
|
let name = values.next().unwrap();
|
||||||
|
if values.len() != 0 {
|
||||||
|
return Err(format!("extra operand ‘{}’", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if name == "-" {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
if !Path::exists(Path::new(name)) {
|
||||||
|
return Err(format!("{}: 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) => {
|
||||||
|
return Err(format!("Invalid wrap size: ‘{}’: {}", num, e));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Config {
|
||||||
|
decode: options.is_present(options::DECODE),
|
||||||
|
ignore_garbage: options.is_present(options::IGNORE_GARBAGE),
|
||||||
|
wrap_cols: cols,
|
||||||
|
to_read: file,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_base_cmd_args(
|
||||||
|
args: impl uucore::Args,
|
||||||
|
name: &str,
|
||||||
|
version: &str,
|
||||||
|
about: &str,
|
||||||
|
usage: &str,
|
||||||
|
) -> Result<Config, String> {
|
||||||
|
let app = App::new(name)
|
||||||
|
.version(version)
|
||||||
|
.about(about)
|
||||||
|
.usage(usage)
|
||||||
|
// 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 arg_list = args
|
||||||
|
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
|
.accept_any();
|
||||||
|
Config::from(app.get_matches_from(arg_list))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_input<'a>(config: &Config, stdin_ref: &'a Stdin) -> Box<dyn Read + 'a> {
|
||||||
|
match &config.to_read {
|
||||||
|
Some(name) => {
|
||||||
|
let file_buf = safe_unwrap!(File::open(Path::new(name)));
|
||||||
|
Box::new(BufReader::new(file_buf)) // as Box<dyn Read>
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
Box::new(stdin_ref.lock()) // as Box<dyn Read>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_input<R: Read>(
|
pub fn handle_input<R: Read>(
|
||||||
input: &mut R,
|
input: &mut R,
|
||||||
|
@ -17,6 +133,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,
|
||||||
) {
|
) {
|
||||||
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 {
|
||||||
|
@ -31,10 +148,14 @@ pub fn handle_input<R: Read>(
|
||||||
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
|
||||||
crash!(1, "Cannot write non-utf8 data");
|
eprintln!("{}: error: Cannot write non-utf8 data", name);
|
||||||
|
exit!(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => crash!(1, "invalid input"),
|
Err(_) => {
|
||||||
|
eprintln!("{}: error: invalid input", name);
|
||||||
|
exit!(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,10 @@ edition = "2018"
|
||||||
path = "src/base64.rs"
|
path = "src/base64.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clap = "2.33"
|
||||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features = ["encoding"] }
|
uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
uu_base32 = { version=">=0.0.6", package="uu_base32", path="../base32"}
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
|
|
|
@ -8,14 +8,14 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
|
use uu_base32::base_common;
|
||||||
|
|
||||||
use uucore::encoding::Format;
|
use uucore::encoding::Format;
|
||||||
use uucore::InvalidEncodingHandling;
|
|
||||||
|
|
||||||
mod base_common;
|
use std::io::{stdin, Read};
|
||||||
|
|
||||||
static SYNTAX: &str = "[OPTION]... [FILE]";
|
static ABOUT: &str = "
|
||||||
static SUMMARY: &str = "Base64 encode or decode FILE, or standard input, to standard output.";
|
|
||||||
static LONG_HELP: &str = "
|
|
||||||
With no FILE, or when FILE is -, read standard input.
|
With no FILE, or when FILE is -, read standard input.
|
||||||
|
|
||||||
The data are encoded as described for the base64 alphabet in RFC
|
The data are encoded as described for the base64 alphabet in RFC
|
||||||
|
@ -24,14 +24,42 @@ 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");
|
||||||
|
|
||||||
|
static BASE_CMD_PARSE_ERROR: i32 = 1;
|
||||||
|
|
||||||
|
fn get_usage() -> String {
|
||||||
|
format!("{0} [OPTION]... [FILE]", executable!())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
base_common::execute(
|
let format = Format::Base64;
|
||||||
args.collect_str(InvalidEncodingHandling::Ignore)
|
let usage = get_usage();
|
||||||
.accept_any(),
|
let name = executable!();
|
||||||
SYNTAX,
|
let config_result: Result<base_common::Config, String> =
|
||||||
SUMMARY,
|
base_common::parse_base_cmd_args(args, name, VERSION, ABOUT, &usage);
|
||||||
LONG_HELP,
|
|
||||||
Format::Base64,
|
if config_result.is_err() {
|
||||||
)
|
match config_result {
|
||||||
|
Ok(_) => panic!(),
|
||||||
|
Err(s) => crash!(BASE_CMD_PARSE_ERROR, "{}", s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a reference to stdin so we can return a locked stdin from
|
||||||
|
// parse_base_cmd_args
|
||||||
|
let stdin_raw = stdin();
|
||||||
|
let config = config_result.unwrap();
|
||||||
|
let mut input: Box<dyn Read> = base_common::get_input(&config, &stdin_raw);
|
||||||
|
|
||||||
|
base_common::handle_input(
|
||||||
|
&mut input,
|
||||||
|
format,
|
||||||
|
config.wrap_cols,
|
||||||
|
config.ignore_garbage,
|
||||||
|
config.decode,
|
||||||
|
name,
|
||||||
|
);
|
||||||
|
|
||||||
|
0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
// This file is part of the uutils coreutils package.
|
|
||||||
//
|
|
||||||
// (c) Jordy Dickinson <jordy.dickinson@gmail.com>
|
|
||||||
// (c) Jian Zeng <anonymousknight96@gmail.com>
|
|
||||||
// (c) Alex Lyon <arcterus@mail.com>
|
|
||||||
//
|
|
||||||
// For the full copyright and license information, please view the LICENSE file
|
|
||||||
// that was distributed with this source code.
|
|
||||||
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{stdin, stdout, BufReader, Read, Write};
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use uucore::encoding::{wrap_print, Data, Format};
|
|
||||||
|
|
||||||
pub fn execute(
|
|
||||||
args: Vec<String>,
|
|
||||||
syntax: &str,
|
|
||||||
summary: &str,
|
|
||||||
long_help: &str,
|
|
||||||
format: Format,
|
|
||||||
) -> i32 {
|
|
||||||
let matches = app!(syntax, summary, long_help)
|
|
||||||
.optflag("d", "decode", "decode data")
|
|
||||||
.optflag(
|
|
||||||
"i",
|
|
||||||
"ignore-garbage",
|
|
||||||
"when decoding, ignore non-alphabetic characters",
|
|
||||||
)
|
|
||||||
.optopt(
|
|
||||||
"w",
|
|
||||||
"wrap",
|
|
||||||
"wrap encoded lines after COLS character (default 76, 0 to disable wrapping)",
|
|
||||||
"COLS",
|
|
||||||
)
|
|
||||||
.parse(args);
|
|
||||||
|
|
||||||
let line_wrap = matches.opt_str("wrap").map(|s| match s.parse() {
|
|
||||||
Ok(n) => n,
|
|
||||||
Err(e) => {
|
|
||||||
crash!(1, "invalid wrap size: ‘{}’: {}", s, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let ignore_garbage = matches.opt_present("ignore-garbage");
|
|
||||||
let decode = matches.opt_present("decode");
|
|
||||||
|
|
||||||
if matches.free.len() > 1 {
|
|
||||||
show_usage_error!("extra operand ‘{}’", matches.free[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches.free.is_empty() || &matches.free[0][..] == "-" {
|
|
||||||
let stdin_raw = stdin();
|
|
||||||
handle_input(
|
|
||||||
&mut stdin_raw.lock(),
|
|
||||||
format,
|
|
||||||
line_wrap,
|
|
||||||
ignore_garbage,
|
|
||||||
decode,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
let path = Path::new(matches.free[0].as_str());
|
|
||||||
let file_buf = safe_unwrap!(File::open(&path));
|
|
||||||
let mut input = BufReader::new(file_buf);
|
|
||||||
handle_input(&mut input, format, line_wrap, ignore_garbage, decode);
|
|
||||||
};
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_input<R: Read>(
|
|
||||||
input: &mut R,
|
|
||||||
format: Format,
|
|
||||||
line_wrap: Option<usize>,
|
|
||||||
ignore_garbage: bool,
|
|
||||||
decode: bool,
|
|
||||||
) {
|
|
||||||
let mut data = Data::new(input, format).ignore_garbage(ignore_garbage);
|
|
||||||
if let Some(wrap) = line_wrap {
|
|
||||||
data = data.line_wrap(wrap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !decode {
|
|
||||||
let encoded = data.encode();
|
|
||||||
wrap_print(&data, encoded);
|
|
||||||
} else {
|
|
||||||
match data.decode() {
|
|
||||||
Ok(s) => {
|
|
||||||
if stdout().write_all(&s).is_err() {
|
|
||||||
// on windows console, writing invalid utf8 returns an error
|
|
||||||
crash!(1, "Cannot write non-utf8 data");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => crash!(1, "invalid input"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -98,7 +98,7 @@ fn test_wrap_bad_arg() {
|
||||||
.arg(wrap_param)
|
.arg(wrap_param)
|
||||||
.arg("b")
|
.arg("b")
|
||||||
.fails()
|
.fails()
|
||||||
.stderr_only("base32: error: invalid wrap size: ‘b’: invalid digit found in string\n");
|
.stderr_only("base32: error: Invalid wrap size: ‘b’: invalid digit found in string\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,21 @@ fn test_encode() {
|
||||||
.pipe_in(input)
|
.pipe_in(input)
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.stdout_only("aGVsbG8sIHdvcmxkIQ==\n");
|
.stdout_only("aGVsbG8sIHdvcmxkIQ==\n");
|
||||||
|
|
||||||
|
// Using '-' as our file
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("-")
|
||||||
|
.pipe_in(input)
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("aGVsbG8sIHdvcmxkIQ==\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_base64_encode_file() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("input-simple.txt")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("SGVsbG8sIFdvcmxkIQo=\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -60,10 +75,9 @@ fn test_wrap() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wrap_no_arg() {
|
fn test_wrap_no_arg() {
|
||||||
for wrap_param in vec!["-w", "--wrap"] {
|
for wrap_param in vec!["-w", "--wrap"] {
|
||||||
new_ucmd!().arg(wrap_param).fails().stderr_only(format!(
|
new_ucmd!().arg(wrap_param).fails().stderr_contains(
|
||||||
"base64: error: Argument to option '{}' missing\n",
|
&"The argument '--wrap <wrap>' requires a value but none was supplied",
|
||||||
if wrap_param == "-w" { "w" } else { "wrap" }
|
);
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +88,24 @@ fn test_wrap_bad_arg() {
|
||||||
.arg(wrap_param)
|
.arg(wrap_param)
|
||||||
.arg("b")
|
.arg("b")
|
||||||
.fails()
|
.fails()
|
||||||
.stderr_only("base64: error: invalid wrap size: ‘b’: invalid digit found in string\n");
|
.stderr_only("base64: error: Invalid wrap size: ‘b’: invalid digit found in string\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_base64_extra_operand() {
|
||||||
|
// Expect a failure when multiple files are specified.
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("a.txt")
|
||||||
|
.arg("a.txt")
|
||||||
|
.fails()
|
||||||
|
.stderr_only("base64: error: extra operand ‘a.txt’");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_base64_file_not_found() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("a.txt")
|
||||||
|
.fails()
|
||||||
|
.stderr_only("base64: error: a.txt: No such file or directory");
|
||||||
|
}
|
||||||
|
|
1
tests/fixtures/base64/input-simple.txt
vendored
Normal file
1
tests/fixtures/base64/input-simple.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Hello, World!
|
Loading…
Add table
Add a link
Reference in a new issue