Skip to main content

romm_cli/commands/
cache.rs

1use anyhow::Result;
2use clap::{Args, Subcommand};
3use serde::Serialize;
4
5use crate::cli_presentation::CliPresentation;
6use crate::commands::OutputFormat;
7use romm_api::core::cache::RomCache;
8
9#[derive(Args, Debug)]
10pub struct CacheCommand {
11    #[command(subcommand)]
12    pub action: CacheAction,
13}
14
15#[derive(Subcommand, Debug)]
16pub enum CacheAction {
17    /// Print the effective ROM cache file path.
18    Path,
19    /// Show ROM cache metadata and parse status.
20    Info,
21    /// Delete the ROM cache file if it exists.
22    Clear,
23}
24
25#[derive(Serialize)]
26struct CacheInfoJson {
27    path: String,
28    exists: bool,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    size_bytes: Option<u64>,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    version: Option<u32>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    entries: Option<usize>,
35    #[serde(skip_serializing_if = "Option::is_none")]
36    parse_error: Option<String>,
37}
38
39pub fn handle(cmd: CacheCommand, presentation: CliPresentation) -> Result<()> {
40    let format = presentation.format;
41    match cmd.action {
42        CacheAction::Path => {
43            println!("{}", RomCache::effective_path().display());
44        }
45        CacheAction::Info => {
46            let info = RomCache::read_info();
47            match format {
48                OutputFormat::Json => {
49                    let out = CacheInfoJson {
50                        path: info.path.display().to_string(),
51                        exists: info.exists,
52                        size_bytes: info.size_bytes,
53                        version: info.version,
54                        entries: info.entry_count,
55                        parse_error: info.parse_error,
56                    };
57                    println!("{}", serde_json::to_string_pretty(&out)?);
58                }
59                OutputFormat::Text => {
60                    println!("path: {}", info.path.display());
61                    println!("exists: {}", info.exists);
62                    if let Some(size) = info.size_bytes {
63                        println!("size_bytes: {size}");
64                    }
65                    if let Some(version) = info.version {
66                        println!("version: {version}");
67                    }
68                    if let Some(count) = info.entry_count {
69                        println!("entries: {count}");
70                    }
71                    if let Some(err) = info.parse_error {
72                        println!("parse_error: {err}");
73                    }
74                }
75            }
76        }
77        CacheAction::Clear => {
78            if presentation.is_json() {
79                let cleared = RomCache::clear_file()?;
80                println!(
81                    "{}",
82                    serde_json::to_string_pretty(&serde_json::json!({ "cleared": cleared }))?
83                );
84            } else if RomCache::clear_file()? {
85                println!("ROM cache cleared.");
86            } else {
87                println!("ROM cache file does not exist.");
88            }
89        }
90    }
91    Ok(())
92}