1use clap::{Args, Parser, Subcommand, ValueEnum};
2
3use crate::shell::Shell;
4
5#[derive(Debug, Parser)]
6#[command(
7 name = "pls",
8 bin_name = "pls",
9 version,
10 about = "The polite sudo.",
11 long_about = None,
12 override_usage = "pls [ARGS...]\n pls init <SHELL>\n pls completions <SHELL>",
13 after_help = "Examples:\n pls chmod 600 secrets.txt\n pls init zsh\n pls completions fish",
14 disable_help_subcommand = true,
15 propagate_version = true
16)]
17pub struct Cli {
18 #[arg(long, hide = true, env = "PLS_HISTORY_COMMAND")]
20 pub history_command: Option<String>,
21
22 #[command(subcommand)]
23 pub command: Option<Command>,
24}
25
26#[derive(Debug, Subcommand)]
27pub enum Command {
28 Init(InitArgs),
30 Completions(CompletionArgs),
32 #[command(external_subcommand)]
33 Exec(Vec<String>),
34}
35
36#[derive(Debug, Args)]
37pub struct InitArgs {
38 pub shell: Shell,
39}
40
41#[derive(Debug, Args)]
42pub struct CompletionArgs {
43 pub shell: Shell,
44}
45
46#[derive(Clone, Debug, Eq, PartialEq)]
47pub enum CommandInput {
48 History(String),
49 Explicit(Vec<String>),
50}
51
52impl Cli {
53 pub fn into_command_input(self) -> CliAction {
54 match self.command {
55 Some(Command::Init(args)) => CliAction::Init(args.shell),
56 Some(Command::Completions(args)) => CliAction::Completions(args.shell),
57 Some(Command::Exec(args)) => CliAction::Exec(CommandInput::Explicit(args)),
58 None => match self.history_command {
59 Some(command) => CliAction::Exec(CommandInput::History(command)),
60 None => CliAction::Exec(CommandInput::Explicit(Vec::new())),
61 },
62 }
63 }
64}
65
66#[derive(Clone, Debug, Eq, PartialEq)]
67pub enum CliAction {
68 Init(Shell),
69 Completions(Shell),
70 Exec(CommandInput),
71}
72
73impl ValueEnum for Shell {
74 fn value_variants<'a>() -> &'a [Self] {
75 &[Shell::Bash, Shell::Zsh, Shell::Fish, Shell::Pwsh, Shell::Nu]
76 }
77
78 fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
79 Some(match self {
80 Shell::Bash => clap::builder::PossibleValue::new("bash"),
81 Shell::Zsh => clap::builder::PossibleValue::new("zsh"),
82 Shell::Fish => clap::builder::PossibleValue::new("fish"),
83 Shell::Pwsh => clap::builder::PossibleValue::new("pwsh").alias("powershell"),
84 Shell::Nu => clap::builder::PossibleValue::new("nu").alias("nushell"),
85 })
86 }
87}