aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cli.rs186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/cli.rs b/src/cli.rs
new file mode 100644
index 0000000..13ef67c
--- /dev/null
+++ b/src/cli.rs
@@ -0,0 +1,186 @@
1use crate::config::Config;
2use crate::database::Database;
3use clap::{Parser, Subcommand};
4use std::path::PathBuf;
5
6#[derive(Parser)]
7#[command(name = "rsp")]
8#[command(about = "Rust music player daemon", long_about = None)]
9pub struct Cli {
10 #[command(subcommand)]
11 pub command: Commands,
12}
13
14#[derive(Subcommand)]
15pub enum Commands {
16 /// Start the daemon
17 Start,
18 /// Stop the daemon
19 Stop,
20 /// Restart the daemon (kill existing and start new)
21 Restart,
22 /// Play a track, album, or artist
23 Play {
24 #[arg(value_name = "QUERY")]
25 query: Option<String>,
26 },
27 /// Pause playback
28 Pause,
29 /// Resume playback
30 Resume,
31 /// Stop playback
32 StopPlayback,
33 /// Skip to next track
34 Next,
35 /// Skip to previous track
36 Previous,
37 /// Set volume (0-100)
38 Volume {
39 #[arg(value_name = "LEVEL")]
40 level: Option<u8>,
41 },
42 /// Shuffle mode
43 Shuffle {
44 #[arg(value_name = "MODE")]
45 mode: Option<String>,
46 },
47 /// Queue management
48 Queue {
49 #[arg(value_name = "POSITION")]
50 position: Option<String>,
51 #[arg(value_name = "QUERY")]
52 query: Option<String>,
53 },
54 /// Show player status
55 Status,
56 /// Scan music paths to populate database
57 Scan {
58 #[arg(long)]
59 force: bool,
60 #[arg(long, value_name = "PATHS")]
61 paths: Option<Vec<PathBuf>>,
62 },
63 /// Settings management
64 Settings {
65 #[command(subcommand)]
66 command: SettingsCommands,
67 },
68}
69
70#[derive(Subcommand)]
71pub enum SettingsCommands {
72 /// Get a setting value
73 Get {
74 #[arg(value_name = "KEY")]
75 key: String,
76 },
77 /// Set a setting value
78 Set {
79 #[arg(value_name = "KEY")]
80 key: String,
81 #[arg(value_name = "VALUE")]
82 value: String,
83 },
84 /// List all settings
85 List,
86 /// Unset a setting
87 Unset {
88 #[arg(value_name = "KEY")]
89 key: String,
90 },
91}
92
93impl Cli {
94 pub fn run(&self) -> Result<(), Box<dyn std::error::Error>> {
95 match &self.command {
96 Commands::Start => {
97 crate::daemon::start_daemon()?;
98 }
99 Commands::Stop => {
100 crate::daemon::stop_daemon()?;
101 }
102 Commands::Restart => {
103 crate::daemon::restart_daemon()?;
104 }
105 Commands::Play { query } => {
106 if let Some(q) = query {
107 crate::daemon::send_command(format!("play {}", q))?;
108 } else {
109 crate::daemon::send_command("play".to_string())?;
110 }
111 }
112 Commands::Pause => {
113 crate::daemon::send_command("pause".to_string())?;
114 }
115 Commands::Resume => {
116 crate::daemon::send_command("resume".to_string())?;
117 }
118 Commands::StopPlayback => {
119 crate::daemon::send_command("stop".to_string())?;
120 }
121 Commands::Next => {
122 crate::daemon::send_command("next".to_string())?;
123 }
124 Commands::Previous => {
125 crate::daemon::send_command("previous".to_string())?;
126 }
127 Commands::Volume { level } => {
128 if let Some(l) = level {
129 crate::daemon::send_command(format!("volume {}", l))?;
130 } else {
131 crate::daemon::send_command("volume".to_string())?;
132 }
133 }
134 Commands::Shuffle { mode } => {
135 if let Some(m) = mode {
136 crate::daemon::send_command(format!("shuffle {}", m))?;
137 } else {
138 crate::daemon::send_command("shuffle".to_string())?;
139 }
140 }
141 Commands::Queue { position, query } => match (position, query) {
142 (None, None) => {
143 crate::daemon::send_command("queue".to_string())?;
144 }
145 (pos, Some(q)) => {
146 let pos = pos.as_deref().unwrap_or("last");
147 crate::daemon::send_command(format!("queue {} {}", pos, q))?;
148 }
149 _ => {}
150 },
151 Commands::Status => {
152 crate::daemon::send_command("status".to_string())?;
153 }
154 Commands::Scan { force, paths } => {
155 let config = Config::load()?;
156 let db = Database::open(&config)?;
157 if let Some(custom_paths) = paths {
158 db.scan_paths(custom_paths, *force)?;
159 } else {
160 db.scan_paths(&config.music_paths, *force)?;
161 }
162 println!("Scan complete");
163 }
164 Commands::Settings { command } => {
165 let mut config = Config::load()?;
166 match command {
167 SettingsCommands::Get { key } => {
168 println!("{}", config.get(key)?);
169 }
170 SettingsCommands::Set { key, value } => {
171 config.set(key, value)?;
172 config.save()?;
173 }
174 SettingsCommands::List => {
175 config.list();
176 }
177 SettingsCommands::Unset { key } => {
178 config.unset(key)?;
179 config.save()?;
180 }
181 }
182 }
183 }
184 Ok(())
185 }
186}