From f67be1d367320655305ea094ba22497331d2b397 Mon Sep 17 00:00:00 2001 From: zack Date: Sun, 27 Jul 2025 15:39:58 -0400 Subject: [PATCH] feat: add clap --- Cargo.lock | 127 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 148 ++++++++++++++++++++++++++++++---------------------- 3 files changed, 213 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 439284e..d76b928 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,6 +23,56 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.98" @@ -165,6 +215,7 @@ name = "ciderd" version = "0.1.0" dependencies = [ "anyhow", + "clap", "color-eyre", "crossbeam-channel", "ctrlc", @@ -176,6 +227,46 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "clap" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + [[package]] name = "color-eyre" version = "0.6.5" @@ -203,6 +294,12 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "core-foundation" version = "0.9.4" @@ -487,6 +584,12 @@ version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "http" version = "1.3.1" @@ -764,6 +867,12 @@ dependencies = [ "serde", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itoa" version = "1.0.15" @@ -896,6 +1005,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "openssl" version = "0.10.73" @@ -1347,6 +1462,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.6.1" @@ -1700,6 +1821,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "valuable" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index ce707fd..dffb0bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] +clap = { version = "4.5.41", features = ["derive"]} ctrlc = "3.4.7" crossbeam-channel = "0.5" rust_socketio = { version = "0.6.0", features = ["async"] } diff --git a/src/main.rs b/src/main.rs index 26ac657..583a49b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use std::{ time::Duration, }; +use clap::{Parser, Subcommand}; use crossbeam_channel::unbounded; use rust_socketio::{ClientBuilder, Payload}; use serde::{Deserialize, Serialize}; @@ -168,6 +169,19 @@ struct StatusUpdate { class: Vec, } +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Cli { + #[command(subcommand)] + command: Option, +} + +#[derive(Subcommand, Clone, Debug)] +enum Commands { + /// Monitor song changes from Cider + Monitor, +} + impl Default for StatusUpdate { fn default() -> Self { Self { @@ -273,76 +287,84 @@ fn main() -> color_eyre::Result<()> { color_eyre::install()?; tracing_subscriber::fmt().pretty().init(); - let ctrlc_receiver = setup_ctrlc_handler(); + let cli = Cli::parse(); - let socket = ClientBuilder::new("http://localhost:10767") - .on("connect", |_, _| { - info!("connecting!"); - }) - .on("API:Playback", |payload, _| { - if let Ok(true) = parse_payload(payload) { - let update_str = serde_json::to_string(&*STATE.read().unwrap()).unwrap(); - println!("{update_str}") - } - }) - .connect(); + match &cli.command { + Some(Commands::Monitor) => { + let ctrlc_receiver = setup_ctrlc_handler(); - 'main_loop: loop { - if let Err(e) = socket.as_ref() { - error!("An error occurred: {e}, retrying..."); + let socket = ClientBuilder::new("http://localhost:10767") + .on("connect", |_, _| { + info!("connecting!"); + }) + .on("API:Playback", |payload, _| { + if let Ok(true) = parse_payload(payload) { + let update_str = serde_json::to_string(&*STATE.read().unwrap()).unwrap(); + println!("{update_str}") + } + }) + .connect(); - match ctrlc_receiver.recv_timeout(Duration::from_secs(1)) { - Ok(_) => { - info!("Shutting down"); + 'main_loop: loop { + if let Err(e) = socket.as_ref() { + error!("An error occurred: {e}, retrying..."); + + match ctrlc_receiver.recv_timeout(Duration::from_secs(1)) { + Ok(_) => { + info!("Shutting down"); + break 'main_loop; + } + Err(_) => continue 'main_loop, + } + } else { + if let Ok(d) = get_now_playing() { + let new_text = format!( + "{} - {}", + d.info.name.as_deref().unwrap_or_default(), + d.info.artist_name.as_deref().unwrap_or_default() + ); + let new_tooltip = format!( + "On the album **{}**", + d.info.album_name.as_deref().unwrap_or_default() + ); + + let mut state_guard = STATE.write().unwrap(); + + if state_guard.text != new_text { + state_guard.text = new_text; + } + if state_guard.tooltip != new_tooltip { + state_guard.tooltip = new_tooltip; + } + drop(state_guard); + } + + if let Ok(d) = get_is_playing() { + let new_text = match d.is_playing { + true => "playing".to_owned(), + false => "paused".to_owned(), + }; + + let mut state_guard = STATE.write().unwrap(); + + if state_guard.text != new_text { + state_guard.class = vec![new_text]; + } + drop(state_guard); + } + + let update_str = serde_json::to_string(&*STATE.read().unwrap()).unwrap(); + println!("{update_str}"); + + ctrlc_receiver.recv().unwrap(); + + socket.as_ref().unwrap().disconnect()?; break 'main_loop; } - Err(_) => continue 'main_loop, } - } else { - if let Ok(d) = get_now_playing() { - let new_text = format!( - "{} - {}", - d.info.name.as_deref().unwrap_or_default(), - d.info.artist_name.as_deref().unwrap_or_default() - ); - let new_tooltip = format!( - "On the album **{}**", - d.info.album_name.as_deref().unwrap_or_default() - ); - - let mut state_guard = STATE.write().unwrap(); - - if state_guard.text != new_text { - state_guard.text = new_text; - } - if state_guard.tooltip != new_tooltip { - state_guard.tooltip = new_tooltip; - } - drop(state_guard); - } - - if let Ok(d) = get_is_playing() { - let new_text = match d.is_playing { - true => "playing".to_owned(), - false => "paused".to_owned(), - }; - - let mut state_guard = STATE.write().unwrap(); - - if state_guard.text != new_text { - state_guard.class = vec![new_text]; - } - drop(state_guard); - } - - let update_str = serde_json::to_string(&*STATE.read().unwrap()).unwrap(); - println!("{update_str}"); - - ctrlc_receiver.recv().unwrap(); - - socket.as_ref().unwrap().disconnect()?; - break 'main_loop; } + + None => {} } Ok(())