use serde::Deserialize;
use crate::Modloader;
#[derive(Debug, Deserialize)]
pub struct Project {
pub slug: String,
pub title: String,
pub description: String,
pub categories: Vec<String>,
pub client_side: Side,
pub server_side: Side,
pub body: String,
pub additional_categories: Option<Vec<String>>,
pub project_type: Type,
pub downloads: u32,
pub icon_url: Option<String>,
pub id: String,
pub team: String,
pub moderator_message: Option<ModeratorMessage>,
pub published: String,
pub updated: String,
pub approved: Option<String>,
pub followers: u32,
pub status: Status,
pub license: License,
pub versions: Vec<String>,
}
#[derive(Debug, Deserialize)]
pub struct License {
pub id: String,
pub name: String,
pub url: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct ModeratorMessage {
pub message: String,
pub body: Option<String>,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Deserialize)]
pub enum Side {
required,
optional,
unsupported
}
#[allow(non_camel_case_types)]
#[derive(Debug, Deserialize)]
pub enum Type {
r#mod,
modpack,
recourcepack
}
#[allow(non_camel_case_types)]
#[derive(Debug, Deserialize)]
pub enum Status {
approved,
rejected,
draft,
unlisted,
archived,
processing,
unknown
}
#[derive(Debug, Deserialize)]
pub struct Version {
pub name: String,
pub version_number: String,
pub changelog: Option<String>,
pub game_versions: Vec<String>,
pub version_type: VersionType,
pub loaders: Vec<String>,
pub featured: bool,
pub id: String,
pub project_id: String,
pub author_id: String,
pub date_published: String,
pub downloads: u32,
pub files: Vec<VersionFile>,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Deserialize)]
pub enum VersionType {
release,
beta,
alpha
}
#[derive(Debug, Deserialize)]
pub struct VersionFile {
pub hashes: Hash,
pub url: String,
pub filename: String,
pub primary: bool,
pub size: u32,
}
#[derive(Debug, Deserialize)]
pub struct Hash {
pub sha512: String,
pub sha1: String,
}
async fn get(api: String, path: String) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let url = format!(r#"{}{}"#, api, path);
dbg!(&url);
let data = reqwest::get(url)
.await?
.bytes()
.await?
.to_vec();
Ok(data)
}
pub async fn project(api: String, name: &str) -> Project {
let url = format!("project/{}", name);
let data = get(api, url);
serde_json::from_slice(&data.await.unwrap()).unwrap()
}
pub async fn projects(api: String, ids: Vec<&str>) -> Vec<Project> {
let all = ids.join(r#"",""#);
let url = format!(r#"projects?ids=["{}"]"#, all);
println!("{}", url);
let data = get(api, url);
serde_json::from_slice(&data.await.unwrap()).unwrap()
}
pub async fn versions(api: String, id: String, loader: Modloader, mc_version: String) -> Vec<Version> {
let loaderstr = match loader {
Modloader::Forge => String::from("forge"),
Modloader::Fabric => String::from("fabric"),
};
let url = format!(r#"project/{}/version?loaders=["{}"]&game_versions=["{}"]"#, id, loaderstr, mc_version);
let data = get(api, url);
serde_json::from_slice(&data.await.unwrap()).unwrap()
}