genius_lyrics/
lib.rs

1extern crate html2text;
2extern crate regex;
3extern crate reqwest;
4extern crate scraper;
5
6use regex::Regex;
7use scraper::{Html, Selector};
8
9/// Errors when parsing lyrics
10
11#[derive(Debug, Clone, Copy)]
12pub enum GetLyricsError {
13    UrlError,
14    NoTextError,
15}
16
17#[inline]
18fn get_lyrics_from_doc(doc: &str) -> Result<String, GetLyricsError> {
19    Ok(Regex::new(r"\[\d*]|/.*|[\[\]]|https:.*")
20        .unwrap()
21        .replace_all(
22            html2text::from_read(
23                match Html::parse_document(doc)
24                    .select(&Selector::parse("div[id=application]").unwrap())
25                    .next()
26                {
27                    Some(x) => x,
28                    None => return Err(GetLyricsError::NoTextError),
29                }
30                    .select(&Selector::parse("div[data-lyrics-container=true]").unwrap())
31                    .fold(String::new(), |acc, e| format!("{}{}", acc, e.html()))
32                    .as_bytes(),
33                1000,
34            )
35                .as_str(),
36            "",
37        )
38        .as_ref()
39        .trim()
40        .to_string())
41}
42
43/// Gets lyrics from Genius by url asynchronously
44///
45/// # Example
46///
47/// ```Rust
48/// extern crate tokio;
49/// use genius_lyrics::get_lyrics_from_url;
50///
51/// #[tokio::main]
52/// async fn main() {
53///     println!(
54///         "{}",
55///         get_lyrics_from_url("https://genius.com/Michael-jackson-bad-lyrics")
56///             .await
57///             .unwrap()
58///     )
59/// }
60/// ```
61///
62
63#[inline]
64pub async fn get_lyrics_from_url(url: &str) -> Result<String, GetLyricsError> {
65    get_lyrics_from_doc(
66        match reqwest::get(url).await {
67            Ok(x) => x,
68            Err(_) => return Err(GetLyricsError::UrlError),
69        }
70            .text()
71            .await
72            .unwrap()
73            .as_str(),
74    )
75}
76
77/// **Blocks thread** and gets lyrics from Genius by url
78///
79/// # Example
80///
81/// ```Rust
82/// use genius_lyrics::get_lyrics_from_url_blocking;
83///
84/// fn main() {
85///     println!("{}", get_lyrics_from_url_blocking("https://genius.com/Michael-jackson-bad-lyrics").unwrap())
86/// }
87/// ```
88///
89
90#[inline]
91pub fn get_lyrics_from_url_blocking(url: &str) -> Result<String, GetLyricsError> {
92    get_lyrics_from_doc(
93        match reqwest::blocking::get(url) {
94            Ok(x) => x,
95            Err(_) => return Err(GetLyricsError::UrlError),
96        }
97            .text()
98            .unwrap()
99            .as_str(),
100    )
101}