romm_cli/commands/
scan.rs1use std::time::Duration;
4
5use anyhow::Result;
6use clap::Args;
7use serde_json::json;
8
9use crate::client::RommClient;
10use crate::core::interrupt::InterruptContext;
11use crate::core::resolve::resolve_platform_id_from_list;
12use crate::endpoints::platforms::ListPlatforms;
13
14use super::library_scan::{run_scan_library_flow, ScanCacheInvalidate, ScanLibraryOptions};
15use super::OutputFormat;
16
17#[derive(Args, Debug)]
18pub struct ScanCommand {
19 #[arg(long)]
21 pub platform: Option<String>,
22
23 #[arg(long)]
25 pub wait: bool,
26
27 #[arg(long, requires = "wait")]
29 pub wait_timeout_secs: Option<u64>,
30}
31
32pub async fn handle(
33 cmd: ScanCommand,
34 client: &RommClient,
35 format: OutputFormat,
36 interrupt: Option<InterruptContext>,
37) -> Result<()> {
38 let slugs: Vec<String> = cmd
39 .platform
40 .as_deref()
41 .map(|s| {
42 s.split(',')
43 .map(|p| p.trim().to_string())
44 .filter(|p| !p.is_empty())
45 .collect()
46 })
47 .unwrap_or_default();
48
49 let task_kwargs = if slugs.is_empty() {
50 None
51 } else {
52 Some(json!({ "platform_slugs": slugs }))
53 };
54
55 let cache_invalidate = if cmd.wait {
56 match cmd.platform.as_deref() {
57 Some(p) if !p.trim().is_empty() && !p.contains(',') => {
58 let platforms = client.call(&ListPlatforms).await?;
59 match resolve_platform_id_from_list(p.trim(), &platforms) {
60 Ok(pid) => ScanCacheInvalidate::Platform(pid),
61 Err(_) => ScanCacheInvalidate::AllPlatforms,
62 }
63 }
64 _ => ScanCacheInvalidate::AllPlatforms,
65 }
66 } else {
67 ScanCacheInvalidate::None
68 };
69
70 let options = ScanLibraryOptions {
71 wait: cmd.wait,
72 wait_timeout: Duration::from_secs(cmd.wait_timeout_secs.unwrap_or(3600)),
73 cache_invalidate,
74 task_kwargs,
75 };
76 run_scan_library_flow(client, options, format, interrupt.as_ref()).await
77}