1mod error;
2mod parser;
3mod retriever;
4
5use error::ParseError;
6use parser::{parse_list, parse_single, USER_AGENT};
7use regex::Regex;
8use reqwest;
9use retriever::{retrieve_async_track, retrieve_async_tracks, retrieve_track, retrieve_tracks};
10
11pub fn retrieve_url(url: &str) -> Result<Vec<String>, ParseError> {
12 let spotify_regex: Regex = Regex::new(r"https?:\/\/(?:embed\.|open\.)spotify\.com\/(track|album|playlist)\/([a-zA-Z0-9]+)(?:\?si=[\w-]+)?").unwrap();
13
14 if let Some(captures) = spotify_regex.captures(url) {
15 let category = captures.get(1).unwrap().as_str();
16 let id = captures.get(2).unwrap().as_str();
17
18 match category {
19 "track" => {
20 let track = retrieve_track(category, id).unwrap();
21 Ok(vec![track])
22 }
23 "playlist" | "album" => {
24 let tracks = retrieve_tracks(category, id).unwrap();
25 Ok(tracks)
26 }
27 _ => Err(ParseError::InvalidUrl),
28 }
29 } else {
30 Err(ParseError::InvalidUrl)
31 }
32}
33
34pub async fn retrieve_async_url(url: &str) -> Result<Vec<String>, ParseError> {
35 let spotify_regex: Regex = Regex::new(r"https?:\/\/(?:embed\.|open\.)spotify\.com\/(track|album|playlist)\/([a-zA-Z0-9]+)(?:\?si=[\w-]+)?").unwrap();
36
37 if let Some(captures) = spotify_regex.captures(url) {
38 let category = captures.get(1).unwrap().as_str();
39 let id = captures.get(2).unwrap().as_str();
40
41 match category {
42 "track" => {
43 let track = retrieve_async_track(category, id).await.unwrap();
44 Ok(vec![track])
45 }
46 "playlist" | "album" => {
47 let tracks = retrieve_async_tracks(category, id).await.unwrap();
48 Ok(tracks)
49 }
50 _ => Err(ParseError::InvalidUrl),
51 }
52 } else {
53 Err(ParseError::InvalidUrl)
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 const TRACK: &str = "https://open.spotify.com/track/4PTG3Z6ehGkBFwjybzWkR8?si=e0a8c8ada8284e43";
62 const MULTIPLE_ARTISTS_TRACK: &str =
63 "https://open.spotify.com/track/1O0SdrryPeGp6eSSUibdgo?si=4ae58febe9e74eae";
64 const PLAYLIST: &str =
65 "https://open.spotify.com/playlist/37i9dQZF1DZ06evO05tE88?si=e0c6f44d176f44e6";
66 const ALBUM: &str =
67 "https://open.spotify.com/album/6eUW0wxWtzkFdaEFsTJto6?si=_grLtlNySNyfJTZr8tP44Q";
68
69 #[test]
70 fn check_track() {
71 let track: Vec<&str> = vec!["Rick Astley - Never Gonna Give You Up"];
72 assert_eq!(retrieve_url(TRACK).unwrap(), track);
73 }
74
75 #[test]
76 fn check_multiple_artists_track() {
77 let track: Vec<&str> = vec!["Will o' the wisp, Rick Astley - Blood on My Tie"];
78 assert_eq!(retrieve_url(MULTIPLE_ARTISTS_TRACK).unwrap(), track);
79 }
80
81 #[test]
82 fn check_playlist() {
83 let playlist: Vec<&str> = vec![
84 "Rick Astley - Never Gonna Give You Up",
85 "Rick Astley - Take Me to Your Heart (2023 Remaster)",
86 "Rick Astley - Cry for Help - Single Edit",
87 "Rick Astley - Never Gonna Stop",
88 "Rick Astley - Together Forever",
89 "Rick Astley - Hold Me in Your Arms (7\" Version)",
90 "Rick Astley - Angels on My Side",
91 "New Kids On The Block, Salt-N-Pepa, Rick Astley, En Vogue - Bring Back The Time",
92 "Rick Astley - Whenever You Need Somebody",
93 "Rick Astley - She Wants to Dance with Me (2023 Remaster)",
94 "Rick Astley - Dippin My Feet",
95 "Rick Astley - My Arms Keep Missing You",
96 "Rick Astley - Don't Say Goodbye",
97 "Rick Astley - Dance",
98 "Rick Astley - Giving Up On Love (7'' Pop Version)",
99 "Rick Astley - Never Gonna Give You Up (Cake Mix)",
100 "Rick Astley - It Would Take a Strong Strong Man",
101 "Rick Astley - Driving Me Crazy",
102 "Rick Astley - Beautiful Life",
103 "Rick Astley - I Don't Want to Lose Her",
104 "Rick Astley - Keep Singing",
105 "Rick Astley - Forever and More",
106 "Rick Astley - Hopelessly",
107 "Rick Astley - When I Fall in Love",
108 "Rick Astley - Every One of Us",
109 "Rick Astley - High Enough",
110 "Rick Astley - Ain't Too Proud to Beg (2023 Remaster)",
111 "Rick Astley - I'll Never Let You Down",
112 "Trevor Horn, Rick Astley - Owner Of A Lonely Heart",
113 "Rick Astley - Letting Go",
114 "Rick Astley - Never Knew Love",
115 "Rick Astley - Lights Out - Radio Edit",
116 "Rick Astley - Try",
117 "Rick Astley - Dial My Number (2023 Remaster)",
118 "Rick Astley - Wish Away",
119 "Rick Astley - Giant",
120 "Rick Astley - Move Right Out",
121 "Rick Astley - Till Then (Time Stands Still) (2023 Remaster)",
122 "Rick Astley - Pray with Me",
123 "Rick Astley - I Don't Want to Be Your Lover",
124 "Will o' the wisp, Rick Astley - Blood on My Tie",
125 "Rick Astley - Can't Help Falling in Love",
126 "Rick Astley - I Like the Sun",
127 "Rick Astley - She Makes Me",
128 "Rick Astley - Body and Soul",
129 "Rick Astley - (They Long to Be) Close to You",
130 "Rick Astley - Unwanted (Official Song from the Podcast)",
131 "Rick Astley - Last Night on Earth",
132 "Rick Astley - Everlong - Acoustic Version",
133 "Rick Astley - Superman",
134 ];
135 assert_eq!(retrieve_url(PLAYLIST).unwrap(), playlist);
136 }
137
138 #[test]
139 fn check_album() {
140 let album: Vec<&str> = vec![
141 "Rick Astley - Never Gonna Give You Up",
142 "Rick Astley - Whenever You Need Somebody",
143 "Rick Astley - Together Forever",
144 "Rick Astley - It Would Take a Strong Strong Man",
145 "Rick Astley - The Love Has Gone",
146 "Rick Astley - Don't Say Goodbye",
147 "Rick Astley - Slipping Away",
148 "Rick Astley - No More Looking for Love",
149 "Rick Astley - You Move Me",
150 "Rick Astley - When I Fall in Love",
151 ];
152 assert_eq!(retrieve_url(ALBUM).unwrap(), album);
153 }
154}