use regex::Regex; #[derive(Debug)] pub enum Error{ IllegalLink(String), ReqwestError(reqwest::Error), JsonError(json::Error), ArticleNotFound, } impl From for Error { fn from(value: reqwest::Error) -> Self { Self::ReqwestError(value) } } impl From for Error { fn from(value: json::Error) -> Self { Self::JsonError(value) } } pub fn slug_from_link(link: String) -> Result { let regex_pattern = Regex::new(r"\.wikipedia\.org\/wiki\/|\?").unwrap(); let link_parts: Vec<&str> = regex_pattern.split(&link).collect(); if link_parts.len() >= 2 { Ok(link_parts[1].to_string()) } else { Err(Error::IllegalLink(link)) } } pub async fn title_from_slug(slug: String) -> Result { let escaped_slug = slug.replace("/", "%2F"); let request_url = format!( "https://api.wikimedia.org/core/v1/wikipedia/en/page/{escaped_slug}/bare" ); let response = reqwest::get(request_url).await?; let json_body = response.text().await?; let body = json::parse(&json_body)?; match body["title"].as_str() { Some(x) => Ok(x.to_string()), None => Err(Error::ArticleNotFound) } } pub async fn post_body(link: String) -> Result { let title = title_from_slug(slug_from_link(link.clone())?).await?; Ok(format!("Today's wikipedia article is {title}\n\n\ {link}\n\n\ #wikipedia").to_string()) } #[cfg(test)] mod tests { use super::*; #[test] fn test_slug_from_link_1() { assert_eq!(slug_from_link("https://en.wikipedia.org/wiki/Buck-a-beer?wprov=sfla1".to_string()).unwrap().as_str(), "Buck-a-beer") } #[test] fn test_slug_from_link_2() { assert_eq!(slug_from_link("https://en.wikipedia.org/wiki/GNU/Linux_naming_controversy".to_string()).unwrap().as_str(), "GNU/Linux_naming_controversy") } #[tokio::test] async fn test_title_from_slug_1() { assert_eq!(title_from_slug("Buck-a-beer".to_string()).await.unwrap().as_str(), "Buck-a-beer") } #[tokio::test] async fn test_title_from_slug_2() { assert_eq!(title_from_slug("GNU/Linux_naming_controversy".to_string()).await.unwrap().as_str(), "GNU/Linux naming controversy") } #[tokio::test] async fn test_post_body_1() { let body = post_body("https://en.wikipedia.org/wiki/GNU%2FLinux_naming_controversy".to_string()).await.unwrap(); let expected = "Today's wikipedia article is GNU/Linux naming controversy\n\n\ https://en.wikipedia.org/wiki/GNU%2FLinux_naming_controversy\n\n\ #wikipedia"; assert_eq!(body, expected) } }