1use super::cmd::Command;
7use crate::Context;
8
9#[derive(
11 Clone,
12 Debug,
13 Default,
14 Eq,
15 Hash,
16 Ord,
17 PartialEq,
18 PartialOrd,
19 clap::Parser,
20 serde::Deserialize,
21 serde::Serialize,
22)]
23#[clap(about, author, long_about = None, version)]
24#[command(arg_required_else_help(true), allow_missing_positional(true))]
25pub struct Cli {
26 #[clap(subcommand)]
27 pub command: Option<Command>,
28 #[clap(long, short = 'C', default_value_t = String::from("Puzzled.toml"))]
29 pub config: String,
30 #[clap(action = clap::ArgAction::Count, long, short)]
31 pub release: u8,
32 #[arg(action = clap::ArgAction::Count, long, short)]
33 pub update: u8,
34 #[arg(action = clap::ArgAction::Count, long, short)]
35 pub verbose: u8,
36}
37
38impl Cli {
39 #[tracing::instrument(target = "cli")]
40 pub fn parse() -> Self {
42 tracing::debug! { "Parsing command line arguments..." }
43 <Self as clap::Parser>::parse()
44 }
45 pub fn command(&self) -> &Option<Command> {
47 &self.command
48 }
49 pub const fn release(&self) -> u8 {
51 self.release
52 }
53 pub const fn verbose(&self) -> u8 {
55 self.verbose
56 }
57 pub const fn update(&self) -> u8 {
59 self.update
60 }
61 pub const fn is_release(&self) -> bool {
63 self.release > 0
64 }
65 pub const fn is_verbose(&self) -> bool {
67 self.verbose > 0
68 }
69 pub const fn is_update(&self) -> bool {
71 self.update > 0
72 }
73 #[tracing::instrument(skip_all, target = "cli")]
75 pub async fn handle(&self, ctx: &mut Context) -> anyhow::Result<()> {
76 if let Some(cmd) = &self.command {
78 tracing::info! { "Executing command: {:?}", cmd.name() }
79 cmd.handle(ctx).await?;
80 }
81 if self.is_release() {
83 tracing::info!(
84 "Release flag has been toggled {n} times",
85 n = self.release()
86 );
87 }
88 if self.is_verbose() {
89 tracing::info! { "Verbose flag has been toggled {n} times", n = self.verbose() }
90 }
91
92 if self.is_update() {
93 tracing::info! { "Update flag has been toggled {n} times", n = self.update() }
94 }
95 Ok(())
96 }
97}