1use clap::{Parser, Subcommand};
8
9use romm_api::client::RommClient;
10use romm_api::config::Config;
11use romm_api::error::RommError;
12
13pub mod api;
14pub mod auth;
15pub mod cache;
16pub mod completions;
17pub mod download;
18pub mod init;
19pub mod library_scan;
20pub mod metadata;
21pub mod platforms;
22pub mod print;
23pub mod roms;
24pub mod scan;
25pub mod sync;
26pub mod update;
27
28#[derive(Clone, Copy, Debug)]
30pub enum OutputFormat {
31 Text,
33 Json,
35}
36
37impl OutputFormat {
38 pub fn from_flags(global_json: bool, local_json: bool) -> Self {
43 if global_json || local_json {
44 OutputFormat::Json
45 } else {
46 OutputFormat::Text
47 }
48 }
49}
50
51#[derive(Parser, Debug)]
56#[command(
57 name = "romm-cli",
58 version,
59 about = "Rust CLI and TUI for the ROMM API",
60 infer_subcommands = true,
61 arg_required_else_help = true,
62 after_help = "Exit codes: 0 success, 1 general failure, 2 usage, 3 config/auth, 4 API/network.\n\
63 See docs/cli.md#exit-codes for scripting examples.\n\
64 JSON output shapes: docs/json-output.md"
65)]
66pub struct Cli {
67 #[arg(short, long, global = true)]
69 pub verbose: bool,
70
71 #[arg(long, global = true)]
73 pub json: bool,
74
75 #[command(subcommand)]
77 pub command: Commands,
78}
79
80#[derive(Subcommand, Debug)]
82pub enum Commands {
83 #[command(visible_alias = "setup")]
85 Init(init::InitCommand),
86 #[command(visible_alias = "call")]
88 Api(api::ApiCommand),
89 #[command(visible_aliases = ["platform", "p", "plats"])]
91 Platforms(platforms::PlatformsCommand),
92 #[command(visible_aliases = ["rom", "r"])]
94 Roms(Box<roms::RomsCommand>),
95 Scan(scan::ScanCommand),
97 Sync(sync::SyncCommand),
99 #[command(visible_aliases = ["dl", "get"])]
101 Download(download::DownloadCommand),
102 Cache(cache::CacheCommand),
104 Auth(auth::AuthCommand),
106 Update,
108 Completions(completions::CompletionsCommand),
110}
111
112pub async fn run(cli: Cli, config: Config) -> Result<(), RommError> {
117 let client = RommClient::new(&config, cli.verbose)?;
118
119 match cli.command {
120 Commands::Completions(_) => Err(RommError::Other(
121 "internal error: completions must be handled in main".into(),
122 )),
123 Commands::Init(_) => Err(RommError::Other(
124 "internal error: init must be handled before load_config".into(),
125 )),
126 command => crate::frontend::cli::run(command, &client, cli.json, cli.verbose).await,
127 }
128}