mod magnetease;
pub mod providers;
use std::fmt;
use async_trait::async_trait;
pub use magnetease::Magnetease;
use providers::{Knaben, Nyaa};
use reqwest::Client;
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Clone, Debug)]
pub struct Magnet {
pub title: String,
pub url: String,
pub seeders: u32,
pub bytes: u64,
}
#[derive(Error)]
pub struct MagneteaseError {
pub kind: MagneteaseErrorKind,
pub provider: WhichProvider,
}
impl fmt::Debug for MagneteaseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MagneteaseError")
.field("kind", &self.kind)
.field("provider", &self.provider.name())
.finish()
}
}
impl fmt::Display for MagneteaseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MagneteaseError")
.field("kind", &self.kind)
.field("provider", &self.provider.name())
.finish()
}
}
#[derive(Error, Debug)]
pub enum MagneteaseErrorKind {
#[error(transparent)]
ConnectionError(#[from] reqwest::Error),
#[error("couldn't scrape html properly")]
HtmlError,
}
pub struct MagneteaseResult {
pub provider: WhichProvider,
pub magnets: Vec<Magnet>,
}
#[async_trait]
pub trait Provider {
fn name(&self) -> &'static str;
fn display_url(&self) -> &'static str;
fn category(&self) -> ProviderCategory {
ProviderCategory::General
}
async fn search(
&self,
client: &Client,
query: &str,
) -> Result<MagneteaseResult, MagneteaseError>;
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum ProviderCategory {
General,
Anime,
}
#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum WhichProvider {
Knaben,
Nyaa,
}
impl WhichProvider {
pub fn all() -> Vec<WhichProvider> {
vec![WhichProvider::Knaben, WhichProvider::Nyaa]
}
pub fn name(&self) -> &'static str {
match self {
WhichProvider::Knaben => Knaben.name(),
WhichProvider::Nyaa => Nyaa.name(),
}
}
pub fn display_url(&self) -> &'static str {
match self {
WhichProvider::Knaben => Knaben.display_url(),
WhichProvider::Nyaa => Nyaa.display_url(),
}
}
pub fn category(&self) -> ProviderCategory {
match self {
WhichProvider::Knaben => ProviderCategory::General,
WhichProvider::Nyaa => ProviderCategory::Anime,
}
}
pub async fn search(
&self,
client: &Client,
query: &str,
) -> Result<MagneteaseResult, MagneteaseError> {
match self {
WhichProvider::Knaben => Knaben.search(client, query).await,
WhichProvider::Nyaa => Nyaa.search(client, query).await,
}
}
}