notch 0.1.10

A compact and fast library for managing Minecraft servers.
Documentation
use serde::Deserialize;
use crate::error::Error;

pub fn fetch_plugins(query: &str) -> Result<Vec<HangarProject>, Error> {
    let url = format!("https://hangar.papermc.io/api/v1/projects?limit=10&offset=0&q={}&sort=-stars", query);
    let response = reqwest::blocking::get(url)?;
    let json: HangarResponse = response.json()?;
    let projects = json.result;
    Ok(projects)
}

#[derive(Deserialize)]
pub struct HangarResponse {
    pub result: Vec<HangarProject>,
}

#[derive(Deserialize)]
pub struct HangarProject {
    #[serde(rename = "createdAt")]
    pub created_at: String,
    pub name: String,
    pub namespace: HangarNamespace,
    pub stats: HangarStats,
    pub category: String,
    #[serde(rename = "lastUpdated")]
    pub last_updated: String,
    pub visibility: String,
    #[serde(rename = "avatarUrl")]
    pub avatar_url: String,
    pub description: String,
}

#[derive(Deserialize)]
pub struct HangarNamespace {
    pub owner: String,
    pub slug: String,
}

#[derive(Deserialize)]
pub struct HangarStats {
    pub views: u32,
    pub downloads: u32,
    #[serde(rename = "recentViews")]
    pub recent_views: u32,
    #[serde(rename = "recentDownloads")]
    pub recent_downloads: u32,
    pub stars: u32,
    pub watchers: u32,
}

const ORDER : [&str; 3] = ["Release", "Snapshot", "Alpha"];

pub fn fetch_plugin_info(author: &str, slug: &str) -> Result<Vec<HangarPlugin>, Error> {
    let url = format!("https://hangar.papermc.io/api/v1/projects/{}/{}/versions", author, slug);
    let response = reqwest::blocking::get(url)?;
    let plugin: HangarPluginResponse = response.json()?;
    let mut plugin = plugin.result;
    plugin.sort_by(|a, b| {
        let a = ORDER.iter().position(|&r| r == a.channel.name).unwrap_or(0);
        let b = ORDER.iter().position(|&r| r == b.channel.name).unwrap_or(0);
        a.cmp(&b)
    });

    Ok(plugin)
}

#[derive(Deserialize)]
pub struct HangarPluginResponse {
    result: Vec<HangarPlugin>
}

#[derive(Deserialize)]
pub struct HangarPlugin {
    pub channel: HangarChannel,
    pub downloads: HangarDownloads,
}

#[derive(Deserialize)]
pub struct HangarChannel {
    pub name: String
}

#[derive(Deserialize)]
pub struct HangarDownloads {
    #[serde(rename = "PAPER")]
    pub paper: Option<HangarDownloadsInfo>,
    #[serde(rename = "WATERFALL")]
    pub waterfall: Option<HangarDownloadsInfo>,
    #[serde(rename = "VELOCITY")]
    pub velocity: Option<HangarDownloadsInfo>,
}

#[derive(Deserialize)]
pub struct HangarDownloadsInfo {
    #[serde(rename = "downloadUrl")]
    pub download_url: Option<String>,
    #[serde(rename = "externalUrl")]
    pub external_url: Option<String>,
}