aboutsummaryrefslogtreecommitdiff
path: root/src-tauri/src/thunderstore/mod.rs
blob: fc2acb02a28b5c9feda045c2e915246f85202e34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! For interacting with Thunderstore API
use crate::constants::{APP_USER_AGENT, BLACKLISTED_MODS};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use ts_rs::TS;

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct ThunderstoreMod {
    pub name: String,
    pub full_name: String,
    pub owner: String,
    pub package_url: String,
    pub date_created: String,
    pub date_updated: String,
    pub uuid4: String,
    pub rating_score: i32,
    pub is_pinned: bool,
    pub is_deprecated: bool,
    pub has_nsfw_content: bool,
    pub categories: Vec<String>,
    pub versions: Vec<ThunderstoreModVersion>,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct ThunderstoreModVersion {
    pub name: String,
    pub full_name: String,
    pub description: String,
    pub icon: String,
    pub version_number: String,
    pub dependencies: Vec<String>,
    pub download_url: String,
    pub downloads: i32,
    pub date_created: String,
    pub website_url: String,
    pub is_active: bool,
    pub uuid4: String,
    pub file_size: i64,
}

/// Performs actual fetch from Thunderstore and returns response
async fn fetch_thunderstore_packages() -> Result<String, reqwest::Error> {
    log::info!("Fetching Thunderstore API");

    // Fetches
    let url = "https://northstar.thunderstore.io/api/v1/package/";

    let client = reqwest::Client::new();
    client
        .get(url)
        .header(reqwest::header::USER_AGENT, APP_USER_AGENT)
        .send()
        .await?
        .text()
        .await
}

/// Queries Thunderstore packages API
#[tauri::command]
pub async fn query_thunderstore_packages_api() -> Result<Vec<ThunderstoreMod>, String> {
    let res = match fetch_thunderstore_packages().await {
        Ok(res) => res,
        Err(err) => {
            let warn_response = format!("Couldn't fetch from Thunderstore: {err}");
            log::warn!("{warn_response}");
            return Err(warn_response);
        }
    };

    // Parse response
    let parsed_json: Vec<ThunderstoreMod> = match serde_json::from_str(&res) {
        Ok(res) => res,
        Err(err) => return Err(err.to_string()),
    };

    // Remove some mods from listing
    let to_remove_set: HashSet<&str> = BLACKLISTED_MODS.iter().copied().collect();
    let filtered_packages = parsed_json
        .into_iter()
        .filter(|package| !to_remove_set.contains(&package.full_name.as_ref()))
        .collect::<Vec<ThunderstoreMod>>();

    Ok(filtered_packages)
}