bitbelay_cli/
lib.rs

1//! Facilities for building your own CLI tools based on `bitbelay`.
2
3pub 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/// A performance evaluation harness for hashing functions.
17#[derive(Debug, Parser)]
18#[clap(author, version, about, long_about = None)]
19pub struct Args {
20    /// The command to run.
21    #[clap(subcommand)]
22    command: Commands,
23
24    /// The data provider.
25    #[clap(short, long, global = true, default_value_t)]
26    provider: AvailableProviders,
27
28    /// Sets the log level to `TRACE`.
29    #[clap(long, global = true)]
30    trace: bool,
31
32    /// Sets the log level to `INFO`.
33    #[clap(short, long, global = true)]
34    verbose: bool,
35}
36
37/// Commands.
38#[derive(Debug, Subcommand)]
39pub enum Commands {
40    /// Runs the avalanche test suite.
41    Avalanche(commands::avalanche::Args),
42
43    /// Runs the chi-squared test suite.
44    ChiSquared(commands::chi_squared::Args),
45
46    /// Runs the correlation test suite.
47    Correlation(commands::correlation::Args),
48
49    /// Runs the speed test suite.
50    Performance(commands::performance::Args),
51}
52
53/// The main function for the wrapper.
54fn 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
98/// A wrapper for an out-of-the-box command line tool for `bitbelay`.
99pub 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}