spotify_cli/cli/commands/
library.rs

1//! Library (liked songs) command handlers
2
3use crate::endpoints::library::{check_saved_tracks, get_saved_tracks, remove_tracks, save_tracks};
4use crate::io::output::{ErrorKind, Response};
5
6use super::{now_playing, with_client};
7
8resource_list!(
9    library_list,
10    get_saved_tracks::get_saved_tracks,
11    "Saved tracks"
12);
13resource_check!(library_check, check_saved_tracks::check_saved_tracks);
14
15pub async fn library_save(ids: &[String], now_playing_flag: bool, dry_run: bool) -> Response {
16    if ids.is_empty() && !now_playing_flag {
17        return Response::err(
18            400,
19            "Provide track IDs or use --now-playing",
20            ErrorKind::Validation,
21        );
22    }
23
24    let explicit_ids = ids.to_vec();
25
26    with_client(|client| async move {
27        let mut all_ids = explicit_ids;
28
29        if now_playing_flag {
30            match now_playing::get_track_id(&client).await {
31                Ok(id) => all_ids.push(id),
32                Err(e) => return e,
33            }
34        }
35
36        let count = all_ids.len();
37
38        if dry_run {
39            return Response::success_with_payload(
40                200,
41                format!("[DRY RUN] Would save {} track(s) to library", count),
42                serde_json::json!({
43                    "dry_run": true,
44                    "action": "save",
45                    "ids": all_ids
46                }),
47            );
48        }
49
50        match save_tracks::save_tracks(&client, &all_ids).await {
51            Ok(_) => Response::success(200, format!("Saved {} track(s)", count)),
52            Err(e) => Response::from_http_error(&e, "Failed to save tracks"),
53        }
54    })
55    .await
56}
57
58pub async fn library_remove(ids: &[String], dry_run: bool) -> Response {
59    if ids.is_empty() {
60        return Response::err(400, "Provide track IDs to remove", ErrorKind::Validation);
61    }
62
63    let ids = ids.to_vec();
64    let count = ids.len();
65
66    if dry_run {
67        return Response::success_with_payload(
68            200,
69            format!("[DRY RUN] Would remove {} track(s) from library", count),
70            serde_json::json!({
71                "dry_run": true,
72                "action": "remove",
73                "ids": ids
74            }),
75        );
76    }
77
78    with_client(|client| async move {
79        match remove_tracks::remove_tracks(&client, &ids).await {
80            Ok(_) => Response::success(200, format!("Removed {} track(s)", count)),
81            Err(e) => Response::from_http_error(&e, "Failed to remove tracks"),
82        }
83    })
84    .await
85}