fujc/curse_api/
mods.rs

1use serde::{Serialize, Deserialize};
2
3use crate::{minecraft::modloader::ModLoaderType, errors::CreatorError};
4
5use super::{CurseApi, CURSE_API_URL};
6
7/// A Minecraft mod struct.
8/// 
9/// This struct is used to deserialize the response from the CurseForge API.
10#[derive(Debug, Deserialize, Serialize)]
11pub struct FilesModResponse {
12    #[serde(rename = "data")]
13    pub data: DataFiles,
14}
15
16/// A list of Minecraft mod files.
17/// 
18/// This struct is used to deserialize the response from the CurseForge API.
19#[derive(Debug, Deserialize, Serialize)]
20pub struct DataFiles {
21    #[serde(rename = "latestFilesIndexes")]
22    pub latest_files_indexes: Vec<ModFiles>,
23}
24
25/// A Minecraft mod file struct.
26/// 
27/// This struct is used to deserialize the response from the CurseForge API.
28#[derive(Debug, Deserialize, Serialize)]
29pub struct ModFiles {
30    #[serde(rename = "fileId")]
31    pub file_id: isize,
32    #[serde(rename = "gameVersion")]
33    pub game_version: String,
34}
35
36/// A list of Minecraft mods.
37/// 
38/// This struct is used to deserialize the response from the CurseForge API.
39#[derive(Debug, Deserialize, Serialize)]
40pub struct SearchModResponse {
41    #[serde(rename = "data")]
42    pub data: Vec<DataMods>,
43}
44
45/// A Minecraft mod struct.
46/// 
47/// This struct is used to deserialize the response from the CurseForge API.
48#[derive(Debug, Deserialize, Serialize)]
49pub struct DataMods {
50    pub id: isize,
51    pub name: String,
52}
53
54/// A list of search filters.
55#[derive(Debug, Deserialize, Serialize)]
56pub enum SearchSortField {
57    #[serde(rename = "featured")]
58    Featured,
59    #[serde(rename = "popularity")]
60    Popularity,
61    #[serde(rename = "lastupdated")]
62    LastUpdated,
63    #[serde(rename = "name")]
64    Name,
65    #[serde(rename = "author")]
66    Author,
67    #[serde(rename = "totaldownloads")]
68    TotalDownloads,
69    #[serde(rename = "category")]
70    Category,
71    #[serde(rename = "game_version")]
72    GameVersion,
73}
74
75/// A struct for searching for Minecraft mods.
76/// 
77/// This struct is used to deserialize the response from the CurseForge API.
78#[derive(Debug, Deserialize, Serialize)]
79pub struct SearchMod {
80    #[serde(rename = "gameId")]
81    pub game_id: isize,
82    #[serde(rename = "gameVersion")]
83    pub game_version: Option<String>,
84    #[serde(rename = "searchFilter")]
85    pub search_filter: Option<String>,
86    #[serde(rename = "modLoaderType")]
87    pub mod_loader_type: Option<ModLoaderType>,
88    #[serde(rename = "sortField")]
89    pub sort_field: Option<SearchSortField>,
90}
91
92
93/// A Minecraft mod struct.
94/// 
95/// This struct is used to deserialize the response from the CurseForge API.
96#[derive(Clone, Debug, Deserialize, Serialize)]
97pub struct CurseMod {
98    pub name: String,
99    pub mod_id: isize,
100    pub file_id: isize,
101}
102
103impl CurseApi {
104    /// Gets a list of Minecraft mods.
105    /// 
106    /// # Arguments
107    /// 
108    /// * `search_query` - The search query to use.
109    /// * `game_version` - The game version to get mods for.
110    /// * `mod_loader` - The mod loader to get mods for.
111    /// 
112    /// # Returns
113    /// 
114    /// A list of Minecraft mods.
115    pub async fn search_mod<T: ToString>(&self, search_query: T, mc_version: String, mod_loader: ModLoaderType)
116        -> Result<SearchModResponse, CreatorError>
117        where
118            T: Into<String>,
119        {
120        let url = format!("{}{}", CURSE_API_URL, "mods/search");
121
122        let query = SearchMod {
123            game_id: 432,
124            game_version: Some(mc_version),
125            search_filter: Some(search_query.into()),
126            mod_loader_type: Some(mod_loader),
127            sort_field: Some(SearchSortField::Name),
128        };
129
130        let response = self.http_client.get(&url).query(&query).send().await?;
131
132        Ok(response.json::<SearchModResponse>().await?)
133    }
134
135    /// Get a file id of a mod.
136    /// 
137    /// # Arguments
138    /// 
139    /// * `mod_id` - The id of the mod.
140    /// * `mod_name` - The name of the mod.
141    /// * `mc_version` - The Minecraft version to get the mod for.
142    /// 
143    /// # Returns
144    /// 
145    /// The file id of the mod.
146     pub async fn get_mod_file_id(
147        &self,
148        mod_id: isize,
149        mod_name: String,
150        mc_version: String
151    ) -> Result<CurseMod, Box<dyn std::error::Error>> {
152        let id = mod_id.clone();
153        let url = format!("{}{}", CURSE_API_URL, format!("mods/{}", mod_id));
154
155        let response = self.http_client.get(&url).send().await?;
156
157        let file_id: Result<FilesModResponse, reqwest::Error> =
158            response.json::<FilesModResponse>().await;
159        // return Ok(file_id.unwrap().data.latest_files_indexes.iter().find(|&x| x.game_version == self.game_version).unwrap().file_id);
160        Ok(CurseMod {
161            name: mod_name,
162            mod_id: id,
163            file_id: file_id
164                .unwrap()
165                .data
166                .latest_files_indexes
167                .iter()
168                .find(|&x| x.game_version == mc_version).unwrap()
169                .file_id,
170        })
171    }
172
173}