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)
}
|