1use crate::metamask;
9use clap::{ArgAction, Args, Parser, Subcommand};
10use tracing::{metadata::LevelFilter, Level};
11use tracing_subscriber::{filter::Directive, EnvFilter};
12
13pub async fn run() -> eyre::Result<()> {
15 let opt = Cli::parse();
17
18 let filter =
20 EnvFilter::builder().with_default_directive(opt.verbosity.directive()).from_env_lossy();
21 tracing_subscriber::fmt().with_env_filter(filter).init();
22
23 match opt.command {
25 Commands::Metamask(m) => m.run().await,
26 }
27}
28
29#[derive(Subcommand)]
31pub enum Commands {
32 #[command(name = "metamask")]
34 Metamask(metamask::Command),
35}
36
37#[derive(Parser)]
38#[command(author, version = "0.1", about = "wallet-rs-cli", long_about = None)]
39struct Cli {
40 #[clap(subcommand)]
42 command: Commands,
43
44 #[clap(flatten)]
45 verbosity: Verbosity,
46}
47
48#[derive(Args)]
49#[command(next_help_heading = "Display")]
50struct Verbosity {
51 #[clap(short, long, action = ArgAction::Count, global = true, default_value_t = 3, verbatim_doc_comment, help_heading = "Display")]
59 verbosity: u8,
60
61 #[clap(long, alias = "silent", short = 'q', global = true, help_heading = "Display")]
63 quiet: bool,
64}
65
66impl Verbosity {
67 fn directive(&self) -> Directive {
70 if self.quiet {
71 LevelFilter::OFF.into()
72 } else {
73 let level = match self.verbosity - 1 {
74 0 => Level::ERROR,
75 1 => Level::WARN,
76 2 => Level::INFO,
77 3 => Level::DEBUG,
78 _ => Level::TRACE,
79 };
80
81 level.into()
82 }
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use eyre::Result;
90
91 #[test]
92 fn test_cli_parse() -> Result<()> {
93 let cli = Cli::parse_from(["wallet-rs-cli", "metamask"]);
95 assert!(matches!(cli.command, Commands::Metamask(_)));
96 Ok(())
97 }
98
99 #[test]
100 fn test_verbosity() {
101 let verbosity = Verbosity { verbosity: 1, quiet: false };
103 assert_eq!(verbosity.directive(), LevelFilter::ERROR.into());
104
105 let verbosity = Verbosity { verbosity: 2, quiet: false };
106 assert_eq!(verbosity.directive(), LevelFilter::WARN.into());
107
108 let verbosity = Verbosity { verbosity: 3, quiet: false };
109 assert_eq!(verbosity.directive(), LevelFilter::INFO.into());
110
111 let verbosity = Verbosity { verbosity: 4, quiet: false };
112 assert_eq!(verbosity.directive(), LevelFilter::DEBUG.into());
113
114 let verbosity = Verbosity { verbosity: 5, quiet: false };
115 assert_eq!(verbosity.directive(), LevelFilter::TRACE.into());
116
117 let verbosity = Verbosity { verbosity: 1, quiet: true };
118 assert_eq!(verbosity.directive(), LevelFilter::OFF.into());
119 }
120}