spotify_cli/cli/commands/
follow.rs

1//! Follow command handlers
2
3use crate::endpoints::user::{
4    check_if_user_follows_artist_or_users, follow_artists_or_users, get_followed_artists,
5    unfollow_artists_or_users,
6};
7use crate::io::output::Response;
8use crate::types::FollowedArtistsResponse;
9
10use super::with_client;
11
12/// Follow artists
13pub async fn follow_artist(ids: &[String], dry_run: bool) -> Response {
14    let ids = ids.to_vec();
15    let count = ids.len();
16
17    if dry_run {
18        return Response::success_with_payload(
19            200,
20            format!("[DRY RUN] Would follow {} artist(s)", count),
21            serde_json::json!({
22                "dry_run": true,
23                "action": "follow",
24                "type": "artist",
25                "ids": ids
26            }),
27        );
28    }
29
30    with_client(|client| async move {
31        match follow_artists_or_users::follow_artists_or_users(&client, "artist", &ids).await {
32            Ok(_) => Response::success(200, format!("Followed {} artist(s)", count)),
33            Err(e) => Response::from_http_error(&e, "Failed to follow artists"),
34        }
35    })
36    .await
37}
38
39/// Follow users
40pub async fn follow_user(ids: &[String], dry_run: bool) -> Response {
41    let ids = ids.to_vec();
42    let count = ids.len();
43
44    if dry_run {
45        return Response::success_with_payload(
46            200,
47            format!("[DRY RUN] Would follow {} user(s)", count),
48            serde_json::json!({
49                "dry_run": true,
50                "action": "follow",
51                "type": "user",
52                "ids": ids
53            }),
54        );
55    }
56
57    with_client(|client| async move {
58        match follow_artists_or_users::follow_artists_or_users(&client, "user", &ids).await {
59            Ok(_) => Response::success(200, format!("Followed {} user(s)", count)),
60            Err(e) => Response::from_http_error(&e, "Failed to follow users"),
61        }
62    })
63    .await
64}
65
66/// Unfollow artists
67pub async fn unfollow_artist(ids: &[String], dry_run: bool) -> Response {
68    let ids = ids.to_vec();
69    let count = ids.len();
70
71    if dry_run {
72        return Response::success_with_payload(
73            200,
74            format!("[DRY RUN] Would unfollow {} artist(s)", count),
75            serde_json::json!({
76                "dry_run": true,
77                "action": "unfollow",
78                "type": "artist",
79                "ids": ids
80            }),
81        );
82    }
83
84    with_client(|client| async move {
85        match unfollow_artists_or_users::unfollow_artists_or_users(&client, "artist", &ids).await {
86            Ok(_) => Response::success(200, format!("Unfollowed {} artist(s)", count)),
87            Err(e) => Response::from_http_error(&e, "Failed to unfollow artists"),
88        }
89    })
90    .await
91}
92
93/// Unfollow users
94pub async fn unfollow_user(ids: &[String], dry_run: bool) -> Response {
95    let ids = ids.to_vec();
96    let count = ids.len();
97
98    if dry_run {
99        return Response::success_with_payload(
100            200,
101            format!("[DRY RUN] Would unfollow {} user(s)", count),
102            serde_json::json!({
103                "dry_run": true,
104                "action": "unfollow",
105                "type": "user",
106                "ids": ids
107            }),
108        );
109    }
110
111    with_client(|client| async move {
112        match unfollow_artists_or_users::unfollow_artists_or_users(&client, "user", &ids).await {
113            Ok(_) => Response::success(200, format!("Unfollowed {} user(s)", count)),
114            Err(e) => Response::from_http_error(&e, "Failed to unfollow users"),
115        }
116    })
117    .await
118}
119
120/// List followed artists
121pub async fn follow_list(limit: u8) -> Response {
122    with_client(|client| async move {
123        match get_followed_artists::get_followed_artists(&client, Some(limit)).await {
124            Ok(Some(payload)) => {
125                match serde_json::from_value::<FollowedArtistsResponse>(payload.clone()) {
126                    Ok(resp) => {
127                        let count = resp.artists.items.len();
128                        let total = resp.artists.total.unwrap_or(count as u32);
129                        Response::success_with_payload(
130                            200,
131                            format!("Following {} artists (showing {})", total, count),
132                            payload,
133                        )
134                    }
135                    Err(_) => Response::success_with_payload(200, "Followed artists", payload),
136                }
137            }
138            Ok(None) => Response::success_with_payload(
139                200,
140                "Not following any artists",
141                serde_json::json!({ "artists": { "items": [] } }),
142            ),
143            Err(e) => Response::from_http_error(&e, "Failed to get followed artists"),
144        }
145    })
146    .await
147}
148
149/// Check if following artists
150pub async fn follow_check_artist(ids: &[String]) -> Response {
151    let ids = ids.to_vec();
152
153    with_client(|client| async move {
154        match check_if_user_follows_artist_or_users::check_if_user_follows_artist_or_users(
155            &client, "artist", &ids,
156        )
157        .await
158        {
159            Ok(Some(payload)) => {
160                Response::success_with_payload(200, "Follow check results", payload)
161            }
162            Ok(None) => {
163                Response::success_with_payload(200, "Follow check results", serde_json::json!([]))
164            }
165            Err(e) => Response::from_http_error(&e, "Failed to check follow status"),
166        }
167    })
168    .await
169}
170
171/// Check if following users
172pub async fn follow_check_user(ids: &[String]) -> Response {
173    let ids = ids.to_vec();
174
175    with_client(|client| async move {
176        match check_if_user_follows_artist_or_users::check_if_user_follows_artist_or_users(
177            &client, "user", &ids,
178        )
179        .await
180        {
181            Ok(Some(payload)) => {
182                Response::success_with_payload(200, "Follow check results", payload)
183            }
184            Ok(None) => {
185                Response::success_with_payload(200, "Follow check results", serde_json::json!([]))
186            }
187            Err(e) => Response::from_http_error(&e, "Failed to check follow status"),
188        }
189    })
190    .await
191}