1pub mod commands;
4
5use std::hash::BuildHasher;
6
7use bitbelay_providers::AvailableProviders;
8use clap::Parser;
9use clap::Subcommand;
10
11use crate::commands::avalanche;
12use crate::commands::chi_squared;
13use crate::commands::correlation;
14use crate::commands::performance;
15
16#[derive(Debug, Parser)]
18#[clap(author, version, about, long_about = None)]
19pub struct Args {
20 #[clap(subcommand)]
22 command: Commands,
23
24 #[clap(short, long, global = true, default_value_t)]
26 provider: AvailableProviders,
27
28 #[clap(long, global = true)]
30 trace: bool,
31
32 #[clap(short, long, global = true)]
34 verbose: bool,
35}
36
37#[derive(Debug, Subcommand)]
39pub enum Commands {
40 Avalanche(commands::avalanche::Args),
42
43 ChiSquared(commands::chi_squared::Args),
45
46 Correlation(commands::correlation::Args),
48
49 Performance(commands::performance::Args),
51}
52
53fn main<H: BuildHasher>(build_hasher: H) -> anyhow::Result<()> {
55 let global_args = Args::parse();
56
57 let log_level = if global_args.trace {
58 tracing::Level::TRACE
59 } else if global_args.verbose {
60 tracing::Level::INFO
61 } else {
62 tracing::Level::ERROR
63 };
64
65 tracing_subscriber::fmt().with_max_level(log_level).init();
66 tracing::info!("Hasher: {}.", std::any::type_name::<H>());
67 tracing::info!("Provider: {}.", global_args.provider);
68
69 match global_args.command {
70 Commands::Avalanche(args) => {
71 avalanche::main(args, build_hasher, global_args.provider.into())
72 }
73 Commands::ChiSquared(args) => {
74 chi_squared::main(args, build_hasher, global_args.provider.into())
75 }
76 Commands::Correlation(args) => {
77 correlation::main::<H, 64>(args, build_hasher, global_args.provider.into())
78 }
79 Commands::Performance(args) => {
80 if global_args.trace || global_args.verbose {
81 tracing::warn!("");
82 tracing::warn!("***********");
83 tracing::warn!("* WARNING *");
84 tracing::warn!("***********");
85 tracing::warn!("");
86 tracing::warn!("The `--verbose` and `--trace` options should not ");
87 tracing::warn!("generally be used with this command, as those options");
88 tracing::warn!("can affect timing! Please don't report any results");
89 tracing::warn!("with those settings enabled.");
90 tracing::warn!("");
91 };
92
93 performance::main(args, build_hasher, global_args.provider.into())
94 }
95 }
96}
97
98pub fn wrapper<H: BuildHasher>(build_hasher: H) -> anyhow::Result<()> {
100 main(build_hasher)
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn verify_cli() {
109 use clap::CommandFactory;
110 Args::command().debug_assert()
111 }
112}