Skip to main content

spotify_parser/
lib.rs

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}