1#![forbid(unsafe_code)]
2#![deny(clippy::all)]
3
4mod commands;
11mod completions;
12
13use crate::commands::{
14 collections::CollectionsCommand, db::DbCommand, generate::GenerateCommand,
15 history::HistoryCommand, import::ImportCommand, new::NewCommand,
16 request::RequestCommand, show::ShowCommand,
17};
18use clap::{CommandFactory, Parser};
19use clap_complete::CompleteEnv;
20use slumber_core::collection::CollectionFile;
21use std::{path::PathBuf, process::ExitCode};
22
23const COMMAND_NAME: &str = "slumber";
24
25#[derive(Debug, Parser)]
31#[clap(author, version, about, name = COMMAND_NAME)]
32pub struct Args {
33 #[command(flatten)]
34 pub global: GlobalArgs,
35 #[command(subcommand)]
36 pub subcommand: Option<CliCommand>,
37}
38
39impl Args {
40 pub fn complete() {
43 CompleteEnv::with_factory(Args::command).complete();
44 }
45
46 pub fn parse() -> Self {
48 <Self as Parser>::parse()
49 }
50}
51
52#[derive(Debug, Parser)]
54pub struct GlobalArgs {
55 #[clap(long, short)]
61 pub file: Option<PathBuf>,
62}
63
64impl GlobalArgs {
65 fn collection_path(&self) -> anyhow::Result<PathBuf> {
68 CollectionFile::try_path(None, self.file.clone())
69 }
70}
71
72#[derive(Clone, Debug, clap::Subcommand)]
74pub enum CliCommand {
75 Collections(CollectionsCommand),
76 Db(DbCommand),
77 Generate(GenerateCommand),
78 History(HistoryCommand),
79 Import(ImportCommand),
80 New(NewCommand),
81 Request(RequestCommand),
82 Show(ShowCommand),
83}
84
85impl CliCommand {
86 pub async fn execute(self, global: GlobalArgs) -> anyhow::Result<ExitCode> {
88 match self {
89 Self::Collections(command) => command.execute(global).await,
90 Self::Db(command) => command.execute(global).await,
91 Self::Generate(command) => command.execute(global).await,
92 Self::History(command) => command.execute(global).await,
93 Self::Import(command) => command.execute(global).await,
94 Self::New(command) => command.execute(global).await,
95 Self::Request(command) => command.execute(global).await,
96 Self::Show(command) => command.execute(global).await,
97 }
98 }
99}
100
101trait Subcommand {
105 async fn execute(self, global: GlobalArgs) -> anyhow::Result<ExitCode>;
107}