Skip to main content

showcase/
showcase.rs

1use clap::{Args, Parser, Subcommand, ValueEnum};
2use clap_tui::Tui;
3use std::path::PathBuf;
4
5#[derive(Debug, Parser, PartialEq, Eq)]
6#[command(
7    name = "showcase",
8    about = "A realistic clap-tui showcase CLI",
9    version = "0.1.0"
10)]
11enum Command {
12    /// Launch the interactive TUI
13    Tui,
14    /// Build the application bundle
15    Build(BuildArgs),
16    /// Run the local development server
17    Serve(ServeArgs),
18    /// Deploy a build to an environment
19    Deploy(DeployArgs),
20    /// Show or update persisted configuration
21    Config {
22        #[command(subcommand)]
23        command: ConfigCommand,
24    },
25}
26
27#[derive(Debug, Args, PartialEq, Eq)]
28struct BuildArgs {
29    /// Emit an optimized production bundle
30    #[arg(short, long)]
31    release: bool,
32
33    /// Output format
34    #[arg(long, value_enum, default_value_t = BuildFormat::Binary)]
35    format: BuildFormat,
36
37    /// Output directory
38    #[arg(long, default_value = "dist")]
39    output: String,
40
41    /// Source directory to build
42    #[arg(value_hint = clap::ValueHint::DirPath)]
43    source: PathBuf,
44}
45
46#[derive(Debug, Args, PartialEq, Eq)]
47struct ServeArgs {
48    /// Host interface to bind
49    #[arg(long, default_value = "127.0.0.1")]
50    host: String,
51
52    /// Port to listen on
53    #[arg(long, default_value_t = 3000)]
54    port: u16,
55
56    /// Rebuild automatically when files change
57    #[arg(short, long)]
58    watch: bool,
59
60    /// Optional config file
61    #[arg(long, value_hint = clap::ValueHint::FilePath)]
62    config: Option<PathBuf>,
63}
64
65#[derive(Debug, Args, PartialEq, Eq)]
66struct DeployArgs {
67    /// Deployment environment
68    #[arg(long, value_enum)]
69    environment: Environment,
70
71    /// Deployment target
72    #[arg(value_enum)]
73    target: DeployTarget,
74
75    /// Preview actions without applying changes
76    #[arg(short = 'n', long)]
77    dry_run: bool,
78
79    /// Repeatable release tags
80    #[arg(long = "tag", short = 't')]
81    tags: Vec<String>,
82}
83
84#[derive(Debug, Subcommand, PartialEq, Eq)]
85enum ConfigCommand {
86    /// Print the effective configuration
87    Show,
88    /// Set a configuration value
89    Set(ConfigSetArgs),
90}
91
92#[derive(Debug, Args, PartialEq, Eq)]
93struct ConfigSetArgs {
94    /// Config key to update
95    key: String,
96
97    /// Config value to store
98    value: String,
99
100    /// Where the setting should be written
101    #[arg(long, value_enum, default_value_t = ConfigScope::Local)]
102    scope: ConfigScope,
103}
104
105#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
106enum BuildFormat {
107    Binary,
108    Tarball,
109    Docker,
110}
111
112#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
113enum Environment {
114    Staging,
115    Production,
116}
117
118#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
119enum DeployTarget {
120    Web,
121    Worker,
122    Jobs,
123}
124
125#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
126enum ConfigScope {
127    Local,
128    Shared,
129    Global,
130}
131
132fn dispatch(command: Command) {
133    match command {
134        Command::Tui => {}
135        other => println!("{other:#?}"),
136    }
137}
138
139fn main() -> Result<(), clap_tui::TuiError> {
140    match Command::parse() {
141        Command::Tui => {
142            if let Some(command) = Tui::<Command>::new().hide_entrypoint("tui")?.run()? {
143                dispatch(command);
144            }
145        }
146        command => dispatch(command),
147    }
148
149    Ok(())
150}