spotify_cli/cli/commands/
pin.rs1use super::init_pin_store;
2use crate::io::output::{ErrorKind, Response};
3use crate::storage::pins::{Pin, ResourceType};
4
5pub async fn pin_add(
6 resource_type: &str,
7 url_or_id: &str,
8 alias: &str,
9 tags: Option<&str>,
10) -> Response {
11 let rtype: ResourceType = match resource_type.parse() {
12 Ok(t) => t,
13 Err(e) => return Response::err(400, &e, ErrorKind::Validation),
14 };
15
16 let id = Pin::extract_id(url_or_id);
17 let tag_list: Vec<String> = tags
18 .map(|t| t.split(',').map(|s| s.trim().to_string()).collect())
19 .unwrap_or_default();
20
21 let pin = Pin::new(rtype, id.clone(), alias.to_string(), tag_list.clone());
22
23 let mut store = match init_pin_store() {
24 Ok(s) => s,
25 Err(e) => return e,
26 };
27
28 match store.add(pin) {
29 Ok(_) => Response::success_with_payload(
30 201,
31 "Pin added",
32 serde_json::json!({
33 "type": resource_type,
34 "id": id,
35 "alias": alias,
36 "tags": tag_list,
37 "uri": format!("spotify:{}:{}", resource_type, id)
38 }),
39 ),
40 Err(e) => {
41 Response::err_with_details(400, "Failed to add pin", ErrorKind::Storage, e.to_string())
42 }
43 }
44}
45
46pub async fn pin_remove(alias_or_id: &str) -> Response {
47 let mut store = match init_pin_store() {
48 Ok(s) => s,
49 Err(e) => return e,
50 };
51
52 match store.remove(alias_or_id) {
53 Ok(removed) => Response::success_with_payload(
54 200,
55 "Pin removed",
56 serde_json::json!({
57 "type": removed.resource_type.as_str(),
58 "id": removed.id,
59 "alias": removed.alias
60 }),
61 ),
62 Err(e) => Response::err_with_details(
63 404,
64 "Failed to remove pin",
65 ErrorKind::NotFound,
66 e.to_string(),
67 ),
68 }
69}
70
71pub async fn pin_list(filter_type: Option<&str>) -> Response {
72 let store = match init_pin_store() {
73 Ok(s) => s,
74 Err(e) => return e,
75 };
76
77 let rtype: Option<ResourceType> = match filter_type {
78 Some(t) => match t.parse() {
79 Ok(rt) => Some(rt),
80 Err(e) => return Response::err(400, &e, ErrorKind::Validation),
81 },
82 None => None,
83 };
84
85 let pins: Vec<serde_json::Value> = store
86 .list(rtype)
87 .iter()
88 .map(|p| {
89 serde_json::json!({
90 "type": p.resource_type.as_str(),
91 "id": p.id,
92 "alias": p.alias,
93 "tags": p.tags,
94 "uri": p.uri()
95 })
96 })
97 .collect();
98
99 Response::success_with_payload(
100 200,
101 format!("{} pin(s)", pins.len()),
102 serde_json::json!({ "pins": pins }),
103 )
104}