spotify_cli/cli/commands/player/
settings.rs1use crate::endpoints::player::{
4 seek_to_position, set_playback_volume, set_repeat_mode, toggle_playback_shuffle,
5};
6use crate::io::output::{ErrorKind, Response};
7
8use crate::cli::commands::with_client;
9
10fn parse_position_to_ms(position: &str) -> Result<u64, String> {
11 let position = position.trim();
12
13 if position.contains(':') {
14 let parts: Vec<&str> = position.split(':').collect();
15 match parts.len() {
16 2 => {
17 let mins: u64 = parts[0]
18 .parse()
19 .map_err(|_| "Invalid minutes".to_string())?;
20 let secs: u64 = parts[1]
21 .parse()
22 .map_err(|_| "Invalid seconds".to_string())?;
23 Ok((mins * 60 + secs) * 1000)
24 }
25 3 => {
26 let hours: u64 = parts[0].parse().map_err(|_| "Invalid hours".to_string())?;
27 let mins: u64 = parts[1]
28 .parse()
29 .map_err(|_| "Invalid minutes".to_string())?;
30 let secs: u64 = parts[2]
31 .parse()
32 .map_err(|_| "Invalid seconds".to_string())?;
33 Ok((hours * 3600 + mins * 60 + secs) * 1000)
34 }
35 _ => Err("Invalid time format. Use mm:ss or hh:mm:ss".to_string()),
36 }
37 } else if let Some(ms_str) = position.strip_suffix("ms") {
38 ms_str
39 .parse()
40 .map_err(|_| "Invalid milliseconds".to_string())
41 } else if let Some(s_str) = position.strip_suffix('s') {
42 let secs: u64 = s_str.parse().map_err(|_| "Invalid seconds".to_string())?;
43 Ok(secs * 1000)
44 } else {
45 let secs: u64 = position
46 .parse()
47 .map_err(|_| "Invalid position. Use: 90, 1:30, 90s, or 5000ms".to_string())?;
48 Ok(secs * 1000)
49 }
50}
51
52pub async fn player_seek(position: &str) -> Response {
53 let position_ms = match parse_position_to_ms(position) {
54 Ok(ms) => ms,
55 Err(e) => return Response::err(400, &e, ErrorKind::Validation),
56 };
57
58 with_client(|client| async move {
59 match seek_to_position::seek_to_position(&client, position_ms).await {
60 Ok(_) => Response::success(204, "Seeked to position"),
61 Err(e) => Response::from_http_error(&e, "Failed to seek"),
62 }
63 })
64 .await
65}
66
67pub async fn player_repeat(mode: &str) -> Response {
68 let mode = mode.to_string();
69 with_client(|client| async move {
70 match set_repeat_mode::set_repeat_mode(&client, &mode).await {
71 Ok(_) => Response::success(204, format!("Repeat mode set to {}", mode)),
72 Err(e) => Response::from_http_error(&e, "Failed to set repeat mode"),
73 }
74 })
75 .await
76}
77
78pub async fn player_volume(percent: u8) -> Response {
79 with_client(|client| async move {
80 match set_playback_volume::set_playback_volume(&client, percent).await {
81 Ok(_) => Response::success(204, format!("Volume set to {}%", percent)),
82 Err(e) => Response::from_http_error(&e, "Failed to set volume"),
83 }
84 })
85 .await
86}
87
88pub async fn player_shuffle(state: &str) -> Response {
89 let enabled = state == "on";
90 with_client(|client| async move {
91 match toggle_playback_shuffle::toggle_playback_shuffle(&client, enabled).await {
92 Ok(_) => Response::success(
93 204,
94 if enabled {
95 "Shuffle enabled"
96 } else {
97 "Shuffle disabled"
98 },
99 ),
100 Err(e) => Response::from_http_error(&e, "Failed to set shuffle"),
101 }
102 })
103 .await
104}