rsomics_common/
threads.rs1use std::num::NonZeroUsize;
2
3use clap::Args;
4
5#[derive(Debug, Default, Clone, Args)]
7#[command(next_help_heading = "Global options")]
8pub struct ThreadArgs {
9 #[arg(short = 't', long, global = true)]
11 threads: Option<NonZeroUsize>,
12}
13
14impl ThreadArgs {
15 #[must_use]
16 pub const fn requested(&self) -> Option<NonZeroUsize> {
17 self.threads
18 }
19}
20
21#[cfg(test)]
22mod tests {
23 use super::*;
24 use clap::{Parser, Subcommand};
25
26 #[derive(Debug, Parser)]
27 struct Cli {
28 #[command(flatten)]
29 threads: ThreadArgs,
30 #[command(subcommand)]
31 command: Command,
32 }
33
34 #[derive(Debug, Subcommand)]
35 enum Command {
36 Run,
37 }
38
39 #[test]
40 fn defaults_to_runtime_selection() {
41 let cli = Cli::parse_from(["test", "run"]);
42 assert_eq!(cli.threads.requested(), None);
43 }
44
45 #[test]
46 fn parses_global_short_and_long_forms() {
47 let before = Cli::parse_from(["test", "-t", "2", "run"]);
48 let after = Cli::parse_from(["test", "run", "--threads", "4"]);
49 assert_eq!(before.threads.requested().map(NonZeroUsize::get), Some(2));
50 assert_eq!(after.threads.requested().map(NonZeroUsize::get), Some(4));
51 }
52
53 #[test]
54 fn rejects_zero() {
55 assert!(Cli::try_parse_from(["test", "--threads", "0", "run"]).is_err());
56 }
57}