magnetease 0.3.1

A library to fetch magnets from the internet
Documentation
use std::collections::HashSet;

use reqwest::Client;

use crate::{
    providers::{knaben::Knaben, nyaa::Nyaa},
    Magnet, MagneteaseError, Provider,
};

pub struct Magnetease {
    client: Client,
    providers: Vec<Box<dyn Provider + Send + Sync>>,
}

impl Default for Magnetease {
    fn default() -> Self {
        Self::new()
    }
}

impl Magnetease {
    pub fn new() -> Self {
        Self {
            client: Client::new(),
            providers: vec![Box::new(Knaben), Box::new(Nyaa)],
        }
    }
}

impl Magnetease {
    pub async fn search(&self, query: &str) -> Result<Vec<Magnet>, MagneteaseError> {
        let mut results = Vec::new();
        let mut seen_urls = HashSet::new();

        for provider in &self.providers {
            let response = provider.search(&self.client, query).await;
            if let Ok(response) = response {
                for magnet in response.magnets {
                    if seen_urls.insert(magnet.url.clone()) {
                        results.push(magnet);
                    };
                }
            }
        }
        results.sort_by(|a, b| b.seeders.cmp(&a.seeders));
        Ok(results)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn magnetease_works() {
        let magnetease = Magnetease::new();
        let magnets = magnetease.search("minecraft").await.unwrap();
        assert!(magnets[0].seeders > magnets[magnets.len() - 1].seeders);
        assert!(!magnets.is_empty());
    }
}