vsm/cli/
wrapper.rs

1//! A wrapper around the clap library
2
3use std::fmt::{Display, Formatter, Result};
4
5use clap::{
6    crate_authors, crate_description, crate_name, crate_version, Arg, ArgAction, ArgMatches,
7    Command,
8};
9use derive_getters::Getters;
10
11use super::commands::{ActiveCommand, Argument, OptionalCommandName, SubCommandName};
12
13/// Wrapper around the clap ArgMatches object
14#[derive(Debug, Getters)]
15pub struct Cli {
16    /// Holds the users passed command
17    active_command: ActiveCommand,
18    /// Holds optional command line value for debug mode
19    debug_mode: bool,
20}
21
22impl Display for Cli {
23    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
24        write!(f, "{}", self.active_command)
25    }
26}
27
28impl Default for Cli {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl Cli {
35    /// Builds a new Cli object
36    #[must_use]
37    pub fn new() -> Self {
38        let arg_matches: ArgMatches = Command::new(crate_name!())
39            .author(crate_authors!())
40            .version(crate_version!())
41            .about(crate_description!())
42            .subcommand_required(true)
43            .arg(
44                Arg::new(OptionalCommandName::DEBUG)
45                    .required(false)
46                    .help("Show debugging messages")
47                    .short('d')
48                    .long(OptionalCommandName::DEBUG)
49                    .action(ArgAction::SetTrue),
50            )
51            .subcommand(
52                Command::new(SubCommandName::LIST)
53                    .arg_required_else_help(false)
54                    .about("List all available vim session files"),
55            )
56            .subcommand(
57                Command::new(SubCommandName::OPEN)
58                    .arg_required_else_help(false)
59                    .about("Load a session file"),
60            )
61            .subcommand(
62                Command::new(SubCommandName::REMOVE)
63                    .arg_required_else_help(false)
64                    .about("Remove a session file"),
65            )
66            .subcommand(
67                Command::new(SubCommandName::VARIANT)
68                    .arg_required_else_help(false)
69                    .about("Change the variation of vim you want to open sessions with"),
70            )
71            .get_matches();
72
73        Self::build_active_command(&arg_matches)
74    }
75
76    /// Private helper function to build the proper active command.
77    ///
78    /// # Arguments
79    ///     - matches clap::ArgMatches object
80    #[allow(clippy::unreachable)]
81    fn build_active_command(matches: &ArgMatches) -> Self {
82        let active_command: ActiveCommand = match matches.subcommand() {
83            Some((SubCommandName::LIST, _)) => {
84                ActiveCommand::new(SubCommandName::LIST, Argument::default())
85            }
86            Some((SubCommandName::OPEN, _)) => {
87                ActiveCommand::new(SubCommandName::OPEN, Argument::default())
88            }
89            Some((SubCommandName::REMOVE, _)) => {
90                ActiveCommand::new(SubCommandName::REMOVE, Argument::default())
91            }
92            Some((SubCommandName::VARIANT, _)) => {
93                ActiveCommand::new(SubCommandName::VARIANT, Argument::default())
94            }
95            _ => unreachable!(),
96        };
97
98        Self {
99            active_command,
100            debug_mode: matches.get_flag(OptionalCommandName::DEBUG),
101        }
102    }
103
104    /// Returns true if the active sub-command is list
105    #[must_use]
106    pub fn list(&self) -> bool {
107        self.active_command.command() == SubCommandName::LIST
108    }
109
110    /// Returns true if the active sub-command is open
111    #[must_use]
112    pub fn open(&self) -> bool {
113        self.active_command.command() == SubCommandName::OPEN
114    }
115
116    /// Returns true if the active sub-command is remove
117    #[must_use]
118    pub fn remove(&self) -> bool {
119        self.active_command.command() == SubCommandName::REMOVE
120    }
121
122    /// Returns true if the active sub-command is update
123    #[must_use]
124    pub fn variant(&self) -> bool {
125        self.active_command.command() == SubCommandName::VARIANT
126    }
127}