leetcode_cli/
cli.rs

1//! Clap Commanders
2use crate::{
3    cmd::{CompletionsArgs, DataArgs, EditArgs, ExecArgs, ListArgs, PickArgs, StatArgs, TestArgs},
4    err::Error,
5};
6use clap::{CommandFactory, Parser, Subcommand};
7use env_logger::Env;
8use log::LevelFilter;
9
10/// This should be called before calling any cli method or printing any output.
11pub fn reset_signal_pipe_handler() {
12    #[cfg(target_family = "unix")]
13    {
14        use nix::sys::signal;
15
16        unsafe {
17            let _ = signal::signal(signal::Signal::SIGPIPE, signal::SigHandler::SigDfl)
18                .map_err(|e| println!("{:?}", e));
19        }
20    }
21}
22
23/// May the Code be with You
24#[derive(Parser)]
25#[command(name = "leetcode", version, about = "May the Code be with You 👻")]
26#[command(arg_required_else_help = true)]
27pub struct Cli {
28    /// Debug mode
29    #[arg(short, long)]
30    pub debug: bool,
31
32    #[command(subcommand)]
33    pub command: Option<Commands>,
34}
35
36#[derive(Subcommand)]
37pub enum Commands {
38    /// Manage Cache
39    #[command(visible_alias = "d", display_order = 1)]
40    Data(DataArgs),
41
42    /// Edit question
43    #[command(visible_alias = "e", display_order = 2)]
44    Edit(EditArgs),
45
46    /// Submit solution
47    #[command(visible_alias = "x", display_order = 3)]
48    Exec(ExecArgs),
49
50    /// List problems
51    #[command(visible_alias = "l", display_order = 4)]
52    List(ListArgs),
53
54    /// Pick a problem
55    #[command(visible_alias = "p", display_order = 5)]
56    Pick(PickArgs),
57
58    /// Show simple chart about submissions
59    #[command(visible_alias = "s", display_order = 6)]
60    Stat(StatArgs),
61
62    /// Test a question
63    #[command(visible_alias = "t", display_order = 7)]
64    Test(TestArgs),
65
66    /// Generate shell Completions
67    #[command(visible_alias = "c", display_order = 8)]
68    Completions(CompletionsArgs),
69}
70
71/// Get matches
72pub async fn main() -> Result<(), Error> {
73    reset_signal_pipe_handler();
74
75    let cli = Cli::parse();
76
77    if cli.debug {
78        env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
79    } else {
80        env_logger::Builder::new()
81            .filter_level(LevelFilter::Info)
82            .format_timestamp(None)
83            .init();
84    }
85
86    match cli.command {
87        Some(Commands::Data(args)) => args.run().await,
88        Some(Commands::Edit(args)) => args.run().await,
89        Some(Commands::Exec(args)) => args.run().await,
90        Some(Commands::List(args)) => args.run().await,
91        Some(Commands::Pick(args)) => args.run().await,
92        Some(Commands::Stat(args)) => args.run().await,
93        Some(Commands::Test(args)) => args.run().await,
94        Some(Commands::Completions(args)) => {
95            let mut cmd = Cli::command();
96            args.run(&mut cmd)
97        }
98        None => Err(Error::MatchError),
99    }
100}