Skip to main content

schemaui_cli/
cli.rs

1use std::path::PathBuf;
2
3use clap::{ArgAction, Args, Parser, Subcommand};
4
5#[cfg(feature = "web")]
6use std::net::IpAddr;
7
8#[derive(Debug, Parser)]
9#[command(
10    name = "schemaui",
11    version,
12    about = "Render JSON Schemas as interactive TUIs or Web UIs"
13)]
14pub struct Cli {
15    #[command(flatten)]
16    pub common: CommonArgs,
17
18    #[command(subcommand)]
19    pub command: Option<Commands>,
20}
21
22#[derive(Debug, Subcommand)]
23pub enum Commands {
24    /// Launch the interactive terminal UI
25    Tui(TuiCommand),
26
27    #[cfg(feature = "web")]
28    /// Launch the interactive web UI instead of the terminal UI
29    Web(WebCommand),
30
31    #[cfg(feature = "web")]
32    /// Precompute Web session snapshots instead of launching the UI
33    WebSnapshot(WebSnapshotCommand),
34
35    /// Precompute TUI FormSchema/LayoutNavModel modules instead of launching the UI
36    TuiSnapshot(TuiSnapshotCommand),
37}
38
39#[derive(Debug, Args, Clone)]
40pub struct TuiCommand {
41    #[command(flatten)]
42    pub common: CommonArgs,
43}
44
45#[cfg(feature = "web")]
46#[derive(Debug, Args, Clone)]
47pub struct WebCommand {
48    #[command(flatten)]
49    pub common: CommonArgs,
50
51    /// Bind address for the temporary HTTP server
52    #[rustfmt::skip]
53    #[arg(alias = "bind", alias = "listen")]
54    #[arg( short = 'l', long = "host", value_name = "IP", default_value = "127.0.0.1" )]
55    pub host: IpAddr,
56
57    /// Bind port for the temporary HTTP server (0 picks a random free port)
58    #[arg(short = 'p', long = "port", value_name = "PORT", default_value_t = 0)]
59    pub port: u16,
60}
61
62#[cfg(feature = "web")]
63#[derive(Debug, Args, Clone)]
64pub struct WebSnapshotCommand {
65    #[command(flatten)]
66    pub common: CommonArgs,
67
68    /// Output directory for generated Web snapshots (JSON + TS)
69    #[arg(long = "out-dir", value_name = "DIR", default_value = "web_snapshots")]
70    pub out_dir: PathBuf,
71
72    /// Name of the exported constant in the generated TS module
73    #[arg(
74        long = "ts-export",
75        value_name = "NAME",
76        default_value = "SessionSnapshot"
77    )]
78    pub ts_export: String,
79}
80
81#[derive(Debug, Args, Clone)]
82pub struct TuiSnapshotCommand {
83    #[command(flatten)]
84    pub common: CommonArgs,
85
86    /// Output directory for generated TUI artifact modules (Rust source)
87    #[arg(long = "out-dir", value_name = "DIR", default_value = "tui_artifacts")]
88    pub out_dir: PathBuf,
89
90    /// Name of the generated TuiArtifacts constructor function
91    #[arg(long = "tui-fn", value_name = "NAME", default_value = "tui_artifacts")]
92    pub tui_fn: String,
93
94    /// Name of the generated FormSchema constructor function
95    #[arg(
96        long = "form-fn",
97        value_name = "NAME",
98        default_value = "tui_form_schema"
99    )]
100    pub form_fn: String,
101
102    /// Name of the generated LayoutNavModel constructor function
103    #[arg(
104        long = "layout-fn",
105        value_name = "NAME",
106        default_value = "tui_layout_nav"
107    )]
108    pub layout_fn: String,
109}
110
111#[derive(Debug, Args, Clone)]
112pub struct CommonArgs {
113    /// Schema spec: file path, inline payload, or "-" for stdin
114    #[arg(short = 's', long = "schema", value_name = "SPEC")]
115    pub schema: Option<String>,
116
117    /// Config spec: file path, inline payload, or "-" for stdin
118    #[arg(short = 'c', long = "config", alias = "data", value_name = "SPEC")]
119    pub config: Option<String>,
120
121    /// Title shown at the top of the UI
122    #[arg(long = "title", value_name = "TEXT")]
123    pub title: Option<String>,
124
125    /// Output destinations ("-" writes to stdout). Accepts multiple values per flag use.
126    #[arg(short = 'o', long = "output", value_name = "DEST", num_args = 1.., action = ArgAction::Append)]
127    pub outputs: Vec<String>,
128
129    /// Override the default temp file location (only used when no other destinations are set)
130    #[arg(long = "temp-file", value_name = "PATH")]
131    pub temp_file: Option<PathBuf>,
132
133    /// Disable writing to the default temp file when no destinations are provided
134    #[arg(long = "no-temp-file")]
135    pub no_temp_file: bool,
136
137    /// Emit compact JSON/TOML rather than pretty formatting
138    #[arg(long = "no-pretty")]
139    pub no_pretty: bool,
140
141    /// Overwrite output files even if they already exist
142    #[arg(short = 'f', long = "force", short_alias = 'y', alias = "yes")]
143    pub force: bool,
144}