use select::document::Document;
use select::node::Node;
use select::predicate::{Attr, Name, Predicate};
pub fn get_anime_url(body: String) -> Result<Vec<String>, &'static str> {
let document = parse_document(&body);
let nodes = find_nodes(&document, "name");
let anime_list: Vec<String> = nodes
.iter()
.filter_map(|node| {
node.attr("href")
.and_then(|href| href.split('/').last())
.map(|url_ending| url_ending.to_string())
})
.collect();
Ok(anime_list)
}
pub fn get_anime_name(body: String) -> Vec<String> {
let document = parse_document(&body);
let nodes = find_nodes(&document, "name");
nodes.iter().map(|node| node.text()).collect()
}
pub fn get_video_url(body: String) -> Vec<String> {
let mut anime_list: Vec<_> = vec![];
let document = Document::from(body.as_str());
for node in document.find(Attr("class", "cf-download").descendant(Name("a"))) {
anime_list.push(node.attr("href").unwrap().to_string());
}
anime_list
}
#[cfg(test)]
mod tests {
use super::*;
use crate::utils;
use crate::URL;
use tokio;
#[tokio::test]
async fn test_get_anime_url() {
let body = utils::get_html(format!("{}{}", URL, "search.html?keyword=Kenka%20Dokugaku"))
.await
.unwrap();
let urls = get_anime_url(body).unwrap();
assert_eq!(
urls,
vec![
"kenka-dokugaku".to_string(),
"kenka-dokugaku-dub".to_string()
]
);
}
#[tokio::test]
async fn test_get_anime_name() {
let body = utils::get_html(format!("{}{}", URL, "search.html?keyword=kenka%20dokugaku"))
.await
.unwrap();
let names = get_anime_name(body);
println!("{:?}", names);
assert_eq!(names, vec!["Kenka Dokugaku", "Kenka Dokugaku (Dub)"]);
}
#[tokio::test]
async fn test_get_anime_url_with_empty_body() {
let body = "".to_string();
let urls = get_anime_url(body).unwrap();
assert!(urls.is_empty());
}
}
fn parse_document(body: &str) -> Document {
Document::from(body)
}
fn find_nodes<'a>(document: &'a Document, selector: &'a str) -> Vec<Node<'a>> {
document
.find(Attr("class", selector).descendant(Name("a")))
.collect()
}