1use anyhow::Result;
8use clap::{Parser, Subcommand};
9
10use crate::client::RommClient;
11use crate::config::Config;
12
13pub mod api;
14pub mod auth;
15pub mod cache;
16pub mod download;
17pub mod init;
18pub mod library_scan;
19pub mod platforms;
20pub mod print;
21pub mod roms;
22pub mod scan;
23pub mod update;
24
25#[derive(Clone, Copy, Debug)]
27pub enum OutputFormat {
28 Text,
30 Json,
32}
33
34impl OutputFormat {
35 pub fn from_flags(global_json: bool, local_json: bool) -> Self {
40 if global_json || local_json {
41 OutputFormat::Json
42 } else {
43 OutputFormat::Text
44 }
45 }
46}
47
48#[derive(Parser, Debug)]
53#[command(
54 name = "romm-cli",
55 version,
56 about = "Rust CLI and TUI for the ROMM API",
57 infer_subcommands = true,
58 arg_required_else_help = true
59)]
60pub struct Cli {
61 #[arg(short, long, global = true)]
63 pub verbose: bool,
64
65 #[arg(long, global = true)]
67 pub json: bool,
68
69 #[command(subcommand)]
71 pub command: Commands,
72}
73
74#[derive(Subcommand, Debug)]
76pub enum Commands {
77 #[command(visible_alias = "setup")]
79 Init(init::InitCommand),
80 #[cfg(feature = "tui")]
82 Tui {
83 #[arg(long)]
85 mock_update: bool,
86 },
87 #[cfg(not(feature = "tui"))]
89 Tui {
90 #[arg(long)]
91 mock_update: bool,
92 },
93 #[command(visible_alias = "call")]
95 Api(api::ApiCommand),
96 #[command(visible_aliases = ["platform", "p", "plats"])]
98 Platforms(platforms::PlatformsCommand),
99 #[command(visible_aliases = ["rom", "r"])]
101 Roms(Box<roms::RomsCommand>),
102 Scan(scan::ScanCommand),
104 #[command(visible_aliases = ["dl", "get"])]
106 Download(download::DownloadCommand),
107 Cache(cache::CacheCommand),
109 Auth(auth::AuthCommand),
111 Update,
113}
114
115pub async fn run(cli: Cli, config: Config) -> Result<()> {
120 let client = RommClient::new(&config, cli.verbose)?;
121
122 match cli.command {
123 Commands::Init(_) => {
124 anyhow::bail!("internal error: init must be handled before load_config");
125 }
126 #[cfg(feature = "tui")]
127 Commands::Tui { .. } => {
128 anyhow::bail!("internal error: TUI must be started via run_interactive from main");
129 }
130 #[cfg(not(feature = "tui"))]
131 Commands::Tui { .. } => anyhow::bail!("this feature requires the tui"),
132 command => crate::frontend::cli::run(command, &client, cli.json).await?,
133 }
134
135 Ok(())
136}