1use anyhow::Result;
8use clap::{Parser, Subcommand};
9
10use crate::client::RommClient;
11use crate::config::Config;
12
13pub mod api;
14pub mod download;
15pub mod init;
16pub mod platforms;
17pub mod print;
18pub mod roms;
19pub mod update;
20
21#[derive(Clone, Copy, Debug)]
23pub enum OutputFormat {
24 Text,
26 Json,
28}
29
30impl OutputFormat {
31 pub fn from_flags(global_json: bool, local_json: bool) -> Self {
33 if global_json || local_json {
34 OutputFormat::Json
35 } else {
36 OutputFormat::Text
37 }
38 }
39}
40
41#[derive(Parser, Debug)]
47#[command(
48 name = "romm-cli",
49 version,
50 about = "Rust CLI and TUI for the ROMM API"
51)]
52pub struct Cli {
53 #[arg(short, long, global = true)]
55 pub verbose: bool,
56
57 #[arg(long, global = true)]
59 pub json: bool,
60
61 #[command(subcommand)]
62 pub command: Commands,
63}
64
65#[derive(Subcommand, Debug)]
67pub enum Commands {
68 #[command(visible_alias = "setup")]
70 Init(init::InitCommand),
71 #[cfg(feature = "tui")]
73 Tui,
74 #[cfg(not(feature = "tui"))]
76 Tui,
77 Api(api::ApiCommand),
79 Platforms(platforms::PlatformsCommand),
81 Roms(roms::RomsCommand),
83 Download(download::DownloadCommand),
85 Update,
87}
88
89pub async fn run(cli: Cli, config: Config) -> Result<()> {
90 let client = RommClient::new(&config, cli.verbose)?;
91
92 match cli.command {
93 Commands::Init(_) => {
94 anyhow::bail!("internal error: init must be handled before load_config");
95 }
96 #[cfg(feature = "tui")]
97 Commands::Tui => crate::frontend::tui::run(client, config).await?,
98 #[cfg(not(feature = "tui"))]
99 Commands::Tui => anyhow::bail!("this feature requires the tui"),
100 command => crate::frontend::cli::run(command, &client, cli.json).await?,
101 }
102
103 Ok(())
104}