I'm attempting to parse a usize
from the command line with clap
. It compiles with no warnings, and cargo clippy -- -W clippy::pedantic
returns no issues. However, it panics, even with the default value.
My Cargo.toml dependencies looks like this
[dependencies]
clap = "3.2.8"
itertools = "0.10.3"
And the actual code is this
use std::collections::HashMap;
use itertools::{self, Itertools};
use clap::{arg, Command};
fn ngram_freq<'a>(s: &'a [&str], n: usize) -> HashMap<&'a [&'a str], usize> {
s.windows(n).counts()
}
fn main() {
let args = Command::new("ngram_freq")
.version("0.1.0")
.author("Nathan McIntosh")
.about("Reads in a file or a set of files, and returns most popular n-grams")
.arg(
arg!(-f --filenames <FILENAME>)
.required(false)
.help("One or more files to read").multiple_values(true))
.arg(
arg!(-t --threshold <THRESHOLD>)
.required(false)
.help("Only show ngrams with that occur with at a frequency above this threshold")
.default_value("2"))
.get_matches();
dbg!(&args);
let threshold = &args
.try_get_one::<usize>("threshold")
.expect("Could not read a threshold value")
.expect("Could not parse threshold value");
let filenames: Vec<String> = args
.get_many("filenames")
.expect("Could not get filenames")
.cloned()
.collect();
let file_contents: Vec<String> = filenames
.iter()
.map(std::fs::read_to_string)
.filter(std::result::Result::is_ok)
.map(std::result::Result::unwrap)
.collect();
let words: Vec<_> = file_contents
.iter()
.flat_map(|f| f.split_whitespace())
.collect();
for n in 1..=3 {
ngram_freq(&words, n)
.iter()
.filter(|(_, &v)| v > **threshold)
.sorted_by(|a, b| b.1.cmp(a.1))
.for_each(|x| println!("{:?}", x));
}
}
And here is how I call it, and the error returned
RUST_BACKTRACE=full ./target/release/ngram_freq -f ~/dev/aoc_2020/*.jl ─╯
[src/main.rs:27] &args = ArgMatches {
args: {
[hash: 2DA78AE236ADEBDA]: MatchedArg {
occurs: 1,
source: Some(
CommandLine,
),
indices: [
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
],
type_id: Some(
TypeId {
t: 4857865405506106372,
},
),
vals: [
[
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
],
],
raw_vals: [
[
"/Users/natemcintosh/dev/aoc_2020/day01.jl",
"/Users/natemcintosh/dev/aoc_2020/day02.jl",
"/Users/natemcintosh/dev/aoc_2020/day03.jl",
"/Users/natemcintosh/dev/aoc_2020/day04.jl",
"/Users/natemcintosh/dev/aoc_2020/day05.jl",
"/Users/natemcintosh/dev/aoc_2020/day06.jl",
"/Users/natemcintosh/dev/aoc_2020/day07.jl",
"/Users/natemcintosh/dev/aoc_2020/day08.jl",
"/Users/natemcintosh/dev/aoc_2020/day09.jl",
"/Users/natemcintosh/dev/aoc_2020/day10.jl",
"/Users/natemcintosh/dev/aoc_2020/day11.jl",
"/Users/natemcintosh/dev/aoc_2020/day12.jl",
"/Users/natemcintosh/dev/aoc_2020/day13.jl",
"/Users/natemcintosh/dev/aoc_2020/day14.jl",
"/Users/natemcintosh/dev/aoc_2020/day15.jl",
"/Users/natemcintosh/dev/aoc_2020/day16.jl",
"/Users/natemcintosh/dev/aoc_2020/day17.jl",
"/Users/natemcintosh/dev/aoc_2020/day18.jl",
"/Users/natemcintosh/dev/aoc_2020/day19.jl",
"/Users/natemcintosh/dev/aoc_2020/day21.jl",
"/Users/natemcintosh/dev/aoc_2020/day22.jl",
"/Users/natemcintosh/dev/aoc_2020/day23.jl",
"/Users/natemcintosh/dev/aoc_2020/day24.jl",
"/Users/natemcintosh/dev/aoc_2020/day25.jl",
],
],
ignore_case: false,
},
[hash: 394AC800F94DBDC5]: MatchedArg {
occurs: 0,
source: Some(
DefaultValue,
),
indices: [
26,
],
type_id: Some(
TypeId {
t: 4857865405506106372,
},
),
vals: [
[
AnyValue {
inner: TypeId {
t: 4857865405506106372,
},
},
],
],
raw_vals: [
[
"2",
],
],
ignore_case: false,
},
},
subcommand: None,
}
thread 'main' panicked at 'Could not read a threshold value: Downcast { actual: TypeId { t: 4857865405506106372 }, expected: TypeId { t: 13834754221672687376 } }', src/main.rs:31:10
stack backtrace:
0: 0x1044a5bd8 - std::backtrace_rs::backtrace::libunwind::trace::ha03082fdb36b8e44
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
1: 0x1044a5bd8 - std::backtrace_rs::backtrace::trace_unsynchronized::hf1acb3d3fce46837
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x1044a5bd8 - std::sys_common::backtrace::_print_fmt::hbc7deaf5374edfd8
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/sys_common/backtrace.rs:66:5
3: 0x1044a5bd8 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::ha9a1a8bf7485458d
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/sys_common/backtrace.rs:45:22
4: 0x1044baf68 - core::fmt::write::h9ee5b099821ae5e1
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/fmt/mod.rs:1196:17
5: 0x1044a376c - std::io::Write::write_fmt::h240449cbf2a536ee
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/io/mod.rs:1654:15
6: 0x1044a7178 - std::sys_common::backtrace::_print::hf65124e94f800e0d
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/sys_common/backtrace.rs:48:5
7: 0x1044a7178 - std::sys_common::backtrace::print::haec7f207d91c0faa
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/sys_common/backtrace.rs:35:9
8: 0x1044a7178 - std::panicking::default_hook::{{closure}}::h321649ccf26de565
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:295:22
9: 0x1044a6e54 - std::panicking::default_hook::h1e736e6294672e8d
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:314:9
10: 0x1044a7650 - std::panicking::rust_panic_with_hook::hd083a3aa5c934ce6
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:698:17
11: 0x1044a7544 - std::panicking::begin_panic_handler::{{closure}}::hb5be8aaa10a229ca
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:588:13
12: 0x1044a60b4 - std::sys_common::backtrace::__rust_end_short_backtrace::h68e10e4f00198298
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/sys_common/backtrace.rs:138:18
13: 0x1044a729c - rust_begin_unwind
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:584:5
14: 0x1044c50fc - core::panicking::panic_fmt::hffc63a015c61fdde
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/panicking.rs:142:14
15: 0x1044c5158 - core::result::unwrap_failed::hd24fd75dfe8b9563
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/result.rs:1785:5
16: 0x104444788 - ngram_freq::main::hd9db2bf6cddd0327
17: 0x104441058 - std::sys_common::backtrace::__rust_begin_short_backtrace::h058b83e5b54a46ca
18: 0x1044461bc - std::rt::lang_start::{{closure}}::hc0275131429ecb59
19: 0x10449f424 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h3b331d3fbbcc71c7
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/ops/function.rs:280:13
20: 0x10449f424 - std::panicking::try::do_call::hff616b6be7bbc015
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:492:40
21: 0x10449f424 - std::panicking::try::h298ba2ba2d72fd07
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:456:19
22: 0x10449f424 - std::panic::catch_unwind::h82d7a0ad94159423
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panic.rs:137:14
23: 0x10449f424 - std::rt::lang_start_internal::{{closure}}::h801a38d4a43d99be
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/rt.rs:128:48
24: 0x10449f424 - std::panicking::try::do_call::h8ecac938bf293f4a
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:492:40
25: 0x10449f424 - std::panicking::try::he8bacc15da046b2c
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:456:19
26: 0x10449f424 - std::panic::catch_unwind::hfbee3bd78d2873c3
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panic.rs:137:14
27: 0x10449f424 - std::rt::lang_start_internal::hbbfe6e663b24763e
at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/rt.rs:128:20
28: 0x104444a64 - _main
Figured it out myself.
The issue was that I needed to add a value_parser
to the clap
builder.
The only thing that changed was the clap Command builder
let args = Command::new("ngram_freq")
.version("0.1.0")
.author("Nathan McIntosh")
.about("Reads in a file or a set of files, and returns most popular n-grams")
.arg(
arg!(-f --filenames <FILENAME>)
.required(false)
.help("One or more files to read")
.multiple_values(true),
)
.arg(
arg!(-t --threshold <THRESHOLD>)
.required(false)
.help("Only show ngrams with that occur with at a frequency above this threshold")
.default_value("2")
.value_parser(clap::value_parser!(usize)),
)
.get_matches();
That said, I do wish that the compiler or clippy could have told me this