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 platforms;
21pub mod print;
22pub mod roms;
23pub mod scan;
24pub mod sync;
25pub mod update;
26
27#[derive(Clone, Copy, Debug)]
29pub enum OutputFormat {
30 Text,
32 Json,
34}
35
36impl OutputFormat {
37 pub fn from_flags(global_json: bool, local_json: bool) -> Self {
42 if global_json || local_json {
43 OutputFormat::Json
44 } else {
45 OutputFormat::Text
46 }
47 }
48}
49
50#[derive(Parser, Debug)]
55#[command(
56 name = "romm-cli",
57 version,
58 about = "Rust CLI and TUI for the ROMM API",
59 infer_subcommands = true,
60 arg_required_else_help = true,
61 after_help = "Exit codes: 0 success, 1 general failure, 2 usage, 3 config/auth, 4 API/network.\n\
62 See README \"Exit codes\" for scripting examples.\n\
63 JSON output shapes: docs/json-output.md"
64)]
65pub struct Cli {
66 #[arg(short, long, global = true)]
68 pub verbose: bool,
69
70 #[arg(long, global = true)]
72 pub json: bool,
73
74 #[command(subcommand)]
76 pub command: Commands,
77}
78
79#[derive(Subcommand, Debug)]
81pub enum Commands {
82 #[command(visible_alias = "setup")]
84 Init(init::InitCommand),
85 #[command(visible_alias = "call")]
87 Api(api::ApiCommand),
88 #[command(visible_aliases = ["platform", "p", "plats"])]
90 Platforms(platforms::PlatformsCommand),
91 #[command(visible_aliases = ["rom", "r"])]
93 Roms(Box<roms::RomsCommand>),
94 Scan(scan::ScanCommand),
96 Sync(sync::SyncCommand),
98 #[command(visible_aliases = ["dl", "get"])]
100 Download(download::DownloadCommand),
101 Cache(cache::CacheCommand),
103 Auth(auth::AuthCommand),
105 Update,
107 Completions(completions::CompletionsCommand),
109}
110
111pub async fn run(cli: Cli, config: Config) -> Result<(), RommError> {
116 let client = RommClient::new(&config, cli.verbose)?;
117
118 match cli.command {
119 Commands::Completions(_) => Err(RommError::Other(
120 "internal error: completions must be handled in main".into(),
121 )),
122 Commands::Init(_) => Err(RommError::Other(
123 "internal error: init must be handled before load_config".into(),
124 )),
125 command => crate::frontend::cli::run(command, &client, cli.json, cli.verbose).await,
126 }
127}