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 sync;
24pub mod update;
25
26#[derive(Clone, Copy, Debug)]
28pub enum OutputFormat {
29 Text,
31 Json,
33}
34
35impl OutputFormat {
36 pub fn from_flags(global_json: bool, local_json: bool) -> Self {
41 if global_json || local_json {
42 OutputFormat::Json
43 } else {
44 OutputFormat::Text
45 }
46 }
47}
48
49#[derive(Parser, Debug)]
54#[command(
55 name = "romm-cli",
56 version,
57 about = "Rust CLI and TUI for the ROMM API",
58 infer_subcommands = true,
59 arg_required_else_help = true
60)]
61pub struct Cli {
62 #[arg(short, long, global = true)]
64 pub verbose: bool,
65
66 #[arg(long, global = true)]
68 pub json: bool,
69
70 #[command(subcommand)]
72 pub command: Commands,
73}
74
75#[derive(Subcommand, Debug)]
77pub enum Commands {
78 #[command(visible_alias = "setup")]
80 Init(init::InitCommand),
81 #[cfg(feature = "tui")]
83 Tui {
84 #[arg(long)]
86 mock_update: bool,
87 },
88 #[cfg(not(feature = "tui"))]
90 Tui {
91 #[arg(long)]
92 mock_update: bool,
93 },
94 #[command(visible_alias = "call")]
96 Api(api::ApiCommand),
97 #[command(visible_aliases = ["platform", "p", "plats"])]
99 Platforms(platforms::PlatformsCommand),
100 #[command(visible_aliases = ["rom", "r"])]
102 Roms(Box<roms::RomsCommand>),
103 Scan(scan::ScanCommand),
105 Sync(sync::SyncCommand),
107 #[command(visible_aliases = ["dl", "get"])]
109 Download(download::DownloadCommand),
110 Cache(cache::CacheCommand),
112 Auth(auth::AuthCommand),
114 Update,
116}
117
118pub async fn run(cli: Cli, config: Config) -> Result<()> {
123 let client = RommClient::new(&config, cli.verbose)?;
124
125 match cli.command {
126 Commands::Init(_) => {
127 anyhow::bail!("internal error: init must be handled before load_config");
128 }
129 #[cfg(feature = "tui")]
130 Commands::Tui { .. } => {
131 anyhow::bail!("internal error: TUI must be started via run_interactive from main");
132 }
133 #[cfg(not(feature = "tui"))]
134 Commands::Tui { .. } => anyhow::bail!("this feature requires the tui"),
135 command => crate::frontend::cli::run(command, &client, cli.json).await?,
136 }
137
138 Ok(())
139}