diff --git a/Cargo.lock b/Cargo.lock index 2a9cb39..49b638b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,25 +80,23 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.17" +version = "4.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47582c09be7c8b32c0ab3a6181825ababb713fde6fff20fc573a3870dd45c6a0" +checksum = "30607dd93c420c6f1f80b544be522a0238a7db35e6a12968d28910983fee0df0" dependencies = [ "atty", "bitflags", "clap_lex", - "indexmap", - "lazy_static", + "once_cell", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" dependencies = [ "os_str_bytes", ] @@ -217,12 +215,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -244,16 +236,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "indexmap" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "instant" version = "0.1.12" @@ -358,6 +340,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" + [[package]] name = "os_str_bytes" version = "6.0.0" @@ -510,12 +498,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "time" version = "0.1.44" diff --git a/Cargo.toml b/Cargo.toml index a639039..807ed74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ license = "MIT" [dependencies] -clap = { version = "^3", features = ["cargo"] } +clap = { version = "^4", features = ["cargo"] } yansi = "^0" atty = "^0" derive_builder = "^0" diff --git a/src/app.rs b/src/app.rs index 68c3573..d5368cf 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,6 @@ -use clap::{self, Arg, Command}; +use clap::{self, value_parser, Arg, ArgAction, Command}; + +// FIXME: use .value_name fn add_input(cmd: Command) -> Command { cmd.arg( @@ -15,7 +17,7 @@ fn add_input_as_option(cmd: Command) -> Command { .long("input") .default_value("-") .long_help("If not present or a single dash, standard input will be used") - .takes_value(true), + .value_parser(value_parser!(usize)), ) } @@ -26,7 +28,7 @@ fn add_min_max(cmd: Command) -> Command { .short('M') .allow_hyphen_values(true) .help("Filter out values bigger than this") - .takes_value(true), + .value_parser(value_parser!(usize)), ) .arg( Arg::new("min") @@ -34,7 +36,7 @@ fn add_min_max(cmd: Command) -> Command { .short('m') .allow_hyphen_values(true) .help("Filter out values smaller than this") - .takes_value(true), + .value_parser(value_parser!(usize)), ) } @@ -56,9 +58,9 @@ the named one will be used). Arg::new("regex") .long("regex") .short('R') + .action(ArgAction::Set) .help("Use a regex to capture input values") - .long_help(LONG_RE_ABOUT) - .takes_value(true), + .long_help(LONG_RE_ABOUT), ) } @@ -67,8 +69,8 @@ fn add_non_capturing_regex(cmd: Command) -> Command { Arg::new("regex") .long("regex") .short('R') - .help("Filter out lines where regex is not present") - .takes_value(true), + .action(ArgAction::Set) + .help("Filter out lines where regex is not present"), ) } @@ -79,7 +81,7 @@ fn add_width(cmd: Command) -> Command { .short('w') .help("Use this many characters as terminal width") .default_value("110") - .takes_value(true), + .value_parser(value_parser!(usize)), ) } @@ -90,22 +92,21 @@ fn add_intervals(cmd: Command) -> Command { .short('i') .help("Use no more than this amount of buckets to classify data") .default_value("20") - .takes_value(true), + .value_parser(value_parser!(usize)), ) } fn add_precision(cmd: Command) -> Command { cmd.arg( Arg::new("precision") - .long("precision") + .long("precision") // FIXME test precision .short('p') .help("Show that number of decimals (if omitted, 'human' units will be used)") - .default_value("-1") - .takes_value(true), + .value_parser(value_parser!(usize)), ) } -pub fn get_app() -> Command<'static> { +pub fn get_app() -> Command { let mut hist = Command::new("hist") .version(clap::crate_version!()) .about("Plot an histogram from input values"); @@ -120,9 +121,10 @@ pub fn get_app() -> Command<'static> { Arg::new("height") .long("height") .short('H') + .action(ArgAction::Set) .help("Use that many `rows` for the plot") .default_value("40") - .takes_value(true), + .value_parser(value_parser!(usize)), ); plot = add_input(add_regex(add_width(add_min_max(add_precision(plot))))); @@ -134,8 +136,7 @@ pub fn get_app() -> Command<'static> { Arg::new("match") .help("Count maches for those strings") .required(true) - .takes_value(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ); let mut timehist = @@ -146,14 +147,14 @@ pub fn get_app() -> Command<'static> { Arg::new("format") .long("format") .short('f') - .help("Use this string formatting") - .takes_value(true), + .action(ArgAction::Set) + .help("Use this string formatting"), ) .arg( Arg::new("duration") .long("duration") - .help("Cap the time interval at that duration (example: '3h 5min')") - .takes_value(true), + .action(ArgAction::Set) + .help("Cap the time interval at that duration (example: '3h 5min')"), ) .arg(Arg::new("early-stop").long("early-stop").help( "If duration flag is used, assume monotonic times and stop as soon as possible", @@ -167,15 +168,14 @@ pub fn get_app() -> Command<'static> { Arg::new("format") .long("format") .short('f') - .help("Use this string formatting") - .takes_value(true), + .action(ArgAction::Set) + .help("Use this string formatting"), ); splittimehist = add_input_as_option(add_width(add_intervals(splittimehist))).arg( Arg::new("match") .help("Count maches for those strings") .required(true) - .takes_value(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ); let mut common_terms = Command::new("common-terms") @@ -187,7 +187,8 @@ pub fn get_app() -> Command<'static> { .short('l') .help("Display that many lines, sorting by most frequent") .default_value("10") - .takes_value(true), + .action(ArgAction::Set) + .value_parser(value_parser!(usize)), ); Command::new("lowcharts") @@ -201,16 +202,15 @@ pub fn get_app() -> Command<'static> { .short('c') .long("color") .help("Use colors in the output") - .possible_values(&["auto", "no", "yes"]) - .default_value("auto") - .takes_value(true), + .value_parser(["auto", "no", "yes"]) + .default_value("auto"), ) .arg( Arg::new("verbose") .short('v') .long("verbose") - .help("Be more verbose") - .takes_value(false), + .action(ArgAction::Set) + .help("Be more verbose"), ) .subcommand(hist) .subcommand(plot) diff --git a/src/main.rs b/src/main.rs index 1eddf74..c46997d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,16 +76,16 @@ fn parse_duration(duration: &str) -> Result /// from an input source. fn get_float_reader(matches: &ArgMatches) -> Result { let mut builder = read::DataReaderBuilder::default(); - if matches.is_present("min") || matches.is_present("max") { - let min = matches.value_of_t("min").unwrap_or(f64::NEG_INFINITY); - let max = matches.value_of_t("max").unwrap_or(f64::INFINITY); + if matches.contains_id("min") || matches.contains_id("max") { + let min = *matches.get_one("min").unwrap_or(&f64::NEG_INFINITY); + let max = *matches.get_one("max").unwrap_or(&f64::INFINITY); if min > max { error!("Minimum should be smaller than maximum"); return Err(()); } builder.range(min..max); } - if let Some(string) = matches.value_of("regex") { + if let Some(&string) = matches.get_one("regex") { match Regex::new(string) { Ok(re) => { builder.regex(re); @@ -105,17 +105,16 @@ fn histogram(matches: &ArgMatches) -> i32 { Ok(r) => r, _ => return 2, }; - let vec = reader.read(matches.value_of("input").unwrap()); + let vec = reader.read(*matches.get_one("input").unwrap()); if !assert_data(&vec, 1) { return 1; } let mut options = plot::HistogramOptions::default(); - let precision_arg: i32 = matches.value_of_t("precision").unwrap(); - if precision_arg > 0 { - options.precision = Some(precision_arg as usize) + if matches.contains_id("precision") { + options.precision = Some(*matches.get_one("precision").unwrap()) }; - options.intervals = matches.value_of_t("intervals").unwrap(); - let width = matches.value_of_t("width").unwrap(); + options.intervals = *matches.get_one("intervals").unwrap(); + let width = *matches.get_one("width").unwrap(); let histogram = plot::Histogram::new(&vec, options); print!("{:width$}", histogram, width = width); 0 @@ -127,11 +126,11 @@ fn plot(matches: &ArgMatches) -> i32 { Ok(r) => r, _ => return 2, }; - let vec = reader.read(matches.value_of("input").unwrap()); + let vec = reader.read(*matches.get_one("input").unwrap()); if !assert_data(&vec, 1) { return 1; } - let precision_arg: i32 = matches.value_of_t("precision").unwrap(); + let precision_arg: i32 = *matches.get_one("precision").unwrap(); let precision = if precision_arg < 0 { None } else { @@ -139,8 +138,8 @@ fn plot(matches: &ArgMatches) -> i32 { }; let plot = plot::XyPlot::new( &vec, - matches.value_of_t("width").unwrap(), - matches.value_of_t("height").unwrap(), + *matches.get_one("width").unwrap(), + *matches.get_one("height").unwrap(), precision, ); print!("{}", plot); @@ -155,7 +154,7 @@ fn matchbar(matches: &ArgMatches) -> i32 { "{:width$}", reader.read_matches( matches.value_of("input").unwrap(), - matches.values_of("match").unwrap().collect() + matches.get_many("match").unwrap().collect() ), width = width ); @@ -266,7 +265,7 @@ fn main() { let matches = app::get_app().get_matches(); configure_output( matches.value_of("color").unwrap(), - matches.is_present("verbose"), + matches.get_flag("verbose"), ); std::process::exit(match matches.subcommand() { Some(("hist", subcommand_matches)) => histogram(subcommand_matches),