use clap::{Parser, Subcommand};
use pwsp::{
types::socket::Request,
utils::daemon::{make_request, wait_for_daemon},
};
use std::{error::Error, path::PathBuf};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Cli {
#[clap(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
Action {
#[clap(subcommand)]
action: Actions,
},
Get {
#[clap(subcommand)]
parameter: GetCommands,
},
Set {
#[clap(subcommand)]
parameter: SetCommands,
},
}
#[derive(Subcommand, Debug)]
enum Actions {
Ping,
Kill,
Pause {
#[clap(short, long)]
id: Option<u32>,
},
Resume {
#[clap(short, long)]
id: Option<u32>,
},
TogglePause {
#[clap(short, long)]
id: Option<u32>,
},
Stop {
#[clap(short, long)]
id: Option<u32>,
},
Play {
file_path: PathBuf,
#[clap(short, long)]
concurrent: bool,
},
ToggleLoop {
#[clap(short, long)]
id: Option<u32>,
},
PlayHotkey { slot: String },
ClearHotkey { slot: String },
ClearHotkeyKey { slot: String },
}
#[derive(Subcommand, Debug)]
enum GetCommands {
IsPaused,
Volume {
#[clap(short, long)]
id: Option<u32>,
},
Position {
#[clap(short, long)]
id: Option<u32>,
},
Duration {
#[clap(short, long)]
id: Option<u32>,
},
State,
Tracks,
Input,
Inputs,
DaemonVersion,
FullState,
Hotkeys,
}
#[derive(Subcommand, Debug)]
enum SetCommands {
Volume {
volume: f32,
#[clap(short, long)]
id: Option<u32>,
},
Position {
position: f32,
#[clap(short, long)]
id: Option<u32>,
},
Input { name: String },
Loop {
enabled: String,
#[clap(short, long)]
id: Option<u32>,
},
Hotkey { slot: String, file_path: PathBuf },
HotkeyKey { slot: String, key_chord: String },
HotkeyActionAndKey {
slot: String,
action: String,
key_chord: String,
},
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
wait_for_daemon().await?;
let request = match cli.command {
Commands::Action { action } => match action {
Actions::Ping => Request::ping(),
Actions::Kill => Request::kill(),
Actions::Pause { id } => Request::pause(id),
Actions::Resume { id } => Request::resume(id),
Actions::TogglePause { id } => Request::toggle_pause(id),
Actions::Stop { id } => Request::stop(id),
Actions::Play {
file_path,
concurrent,
} => Request::play(&file_path.to_string_lossy(), concurrent),
Actions::ToggleLoop { id } => Request::toggle_loop(id),
Actions::PlayHotkey { slot } => Request::play_hotkey(&slot),
Actions::ClearHotkey { slot } => Request::clear_hotkey(&slot),
Actions::ClearHotkeyKey { slot } => Request::clear_hotkey_key(&slot),
},
Commands::Get { parameter } => match parameter {
GetCommands::IsPaused => Request::get_is_paused(),
GetCommands::Volume { id } => Request::get_volume(id),
GetCommands::Position { id } => Request::get_position(id),
GetCommands::Duration { id } => Request::get_duration(id),
GetCommands::State => Request::get_state(),
GetCommands::Tracks => Request::get_tracks(),
GetCommands::Input => Request::get_input(),
GetCommands::Inputs => Request::get_inputs(),
GetCommands::DaemonVersion => Request::get_daemon_version(),
GetCommands::FullState => Request::get_full_state(),
GetCommands::Hotkeys => Request::get_hotkeys(),
},
Commands::Set { parameter } => match parameter {
SetCommands::Volume { volume, id } => Request::set_volume(volume, id),
SetCommands::Position { position, id } => Request::seek(position, id),
SetCommands::Input { name } => Request::set_input(&name),
SetCommands::Loop { enabled, id } => Request::set_loop(&enabled, id),
SetCommands::Hotkey { slot, file_path } => {
Request::set_hotkey(&slot, &file_path.to_string_lossy())
}
SetCommands::HotkeyKey { slot, key_chord } => {
Request::set_hotkey_key(&slot, &key_chord)
}
SetCommands::HotkeyActionAndKey {
slot,
action,
key_chord,
} => Request::set_hotkey_action_and_key(
&slot,
&serde_json::from_str::<Request>(&action)?,
&key_chord,
),
},
};
let response = make_request(request)
.await
.map_err(|e| e as Box<dyn Error>)?;
println!("{} : {}", response.status, response.message);
Ok(())
}