1use clap::{Parser, Subcommand};
8
9use crate::client::RommClient;
10use crate::config::Config;
11use crate::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)]
62pub struct Cli {
63 #[arg(short, long, global = true)]
65 pub verbose: bool,
66
67 #[arg(long, global = true)]
69 pub json: bool,
70
71 #[command(subcommand)]
73 pub command: Commands,
74}
75
76#[derive(Subcommand, Debug)]
78pub enum Commands {
79 #[command(visible_alias = "setup")]
81 Init(init::InitCommand),
82 #[cfg(feature = "tui")]
84 Tui {
85 #[arg(long)]
87 mock_update: bool,
88 },
89 #[cfg(not(feature = "tui"))]
91 Tui {
92 #[arg(long)]
93 mock_update: bool,
94 },
95 #[command(visible_alias = "call")]
97 Api(api::ApiCommand),
98 #[command(visible_aliases = ["platform", "p", "plats"])]
100 Platforms(platforms::PlatformsCommand),
101 #[command(visible_aliases = ["rom", "r"])]
103 Roms(Box<roms::RomsCommand>),
104 Scan(scan::ScanCommand),
106 Sync(sync::SyncCommand),
108 #[command(visible_aliases = ["dl", "get"])]
110 Download(download::DownloadCommand),
111 Cache(cache::CacheCommand),
113 Auth(auth::AuthCommand),
115 Update,
117 Completions(completions::CompletionsCommand),
119}
120
121pub async fn run(cli: Cli, config: Config) -> Result<(), RommError> {
126 let client = RommClient::new(&config, cli.verbose)?;
127
128 match cli.command {
129 Commands::Completions(_) => Err(RommError::Other(
130 "internal error: completions must be handled in main".into(),
131 )),
132 Commands::Init(_) => Err(RommError::Other(
133 "internal error: init must be handled before load_config".into(),
134 )),
135 #[cfg(feature = "tui")]
136 Commands::Tui { .. } => Err(RommError::Other(
137 "internal error: TUI must be started via run_interactive from main".into(),
138 )),
139 #[cfg(not(feature = "tui"))]
140 Commands::Tui { .. } => Err(RommError::Other("this feature requires the tui".into())),
141 command => crate::frontend::cli::run(command, &client, cli.json).await,
142 }
143}