Skip to main content

modrinth_wrapper/
models.rs

1use serde::{Deserialize, Serialize};
2
3/// 一致的 Project 接口封装,使得无论是直接查询 `Project` 还是从 `SearchHit` 返回的结果
4/// 都可以用相似的逻辑进行处理。
5pub trait ProjectInfo {
6    fn get_id(&self) -> &str;
7    fn get_slug(&self) -> Option<&str>;
8    fn get_title(&self) -> Option<&str>;
9    fn get_description(&self) -> Option<&str>;
10    fn get_categories(&self) -> Option<&[String]>;
11    fn get_client_side(&self) -> Option<&str>;
12    fn get_server_side(&self) -> Option<&str>;
13    fn get_project_type(&self) -> &str;
14    fn get_downloads(&self) -> i32;
15    fn get_versions(&self) -> &[String];
16    fn get_followers(&self) -> i32;
17    fn get_author(&self) -> &str;
18    fn get_date_created(&self) -> &str;
19    fn get_date_modified(&self) -> &str;
20}
21
22/// 发送请求或者通过 ID/Slug 单个获取项目时的完整信息。
23#[derive(Debug, Serialize, Deserialize)]
24pub struct Project {
25    /// The ID of the project. encoded as a base62 string.
26    pub id: String,
27    /// The ID of the team that has ownership of this project.
28    pub team: String,
29    /// The date the project was published (ISO-8601).
30    pub published: String,
31    /// The date the project was last updated (ISO-8601).
32    pub updated: String,
33    /// The number of followers the project has.
34    pub followers: i32,
35    /// A list of version IDs associated with this project.
36    pub versions: Vec<String>,
37    /// The number of times the project has been downloaded.
38    pub downloads: i32,
39    /// The type of project (mod, modpack, resourcepack, shader).
40    pub project_type: String,
41    /// The slug of a project, used for vanity URLs.
42    pub slug: Option<String>,
43    /// The title of the project.
44    pub title: Option<String>,
45    /// A short description of the project.
46    pub description: Option<String>,
47    /// Available game versions.
48    pub game_versions: Option<Vec<String>>,
49    /// Supported loaders (e.g. fabric, forge).
50    pub loaders: Option<Vec<String>>,
51    /// Categories applied to the project.
52    pub categories: Option<Vec<String>>,
53    /// Indicates support status on the client (required, optional, unsupported, unknown).
54    pub client_side: Option<String>,
55    /// Indicates support status on the server (required, optional, unsupported, unknown).
56    pub server_side: Option<String>,
57    /// A long-form description of the project, typically markdown.
58    pub body: Option<String>,
59    /// The license of the project.
60    pub license: Option<License>,
61}
62
63#[derive(Debug, Serialize, Deserialize)]
64pub struct License {
65    pub id: String,
66    pub name: String,
67    pub url: Option<String>,
68}
69
70impl ProjectInfo for Project {
71    fn get_id(&self) -> &str { &self.id }
72    fn get_slug(&self) -> Option<&str> { self.slug.as_deref() }
73    fn get_title(&self) -> Option<&str> { self.title.as_deref() }
74    fn get_description(&self) -> Option<&str> { self.description.as_deref() }
75    fn get_categories(&self) -> Option<&[String]> { self.categories.as_deref() }
76    fn get_client_side(&self) -> Option<&str> { self.client_side.as_deref() }
77    fn get_server_side(&self) -> Option<&str> { self.server_side.as_deref() }
78    fn get_project_type(&self) -> &str { &self.project_type }
79    fn get_downloads(&self) -> i32 { self.downloads }
80    fn get_versions(&self) -> &[String] { &self.versions }
81    fn get_followers(&self) -> i32 { self.followers }
82    fn get_author(&self) -> &str { &self.team }
83    fn get_date_created(&self) -> &str { &self.published }
84    fn get_date_modified(&self) -> &str { &self.updated }
85}
86
87/// 搜索接口中返回的单条目,它的结构与 `Project` 高度类似,
88/// 但 Modrinth API 在部分属性名的设计上会有不同。
89#[derive(Debug, Serialize, Deserialize)]
90pub struct SearchHit {
91    /// The type of project (mod, modpack, resourcepack, shader).
92    pub project_type: String,
93    /// The total number of downloads.
94    pub downloads: i32,
95    /// The project's ID.
96    pub project_id: String,
97    /// The username or team that created the project.
98    pub author: String,
99    /// The latest versions available.
100    pub versions: Vec<String>,
101    /// The number of followers.
102    pub follows: i32,
103    /// Date created (ISO-8601).
104    pub date_created: String,
105    /// Date last modified (ISO-8601).
106    pub date_modified: String,
107    /// The project's license short-ID.
108    pub license: String,
109    /// The project slug.
110    pub slug: Option<String>,
111    /// The project title.
112    pub title: Option<String>,
113    /// The project description.
114    pub description: Option<String>,
115    /// A list of associated categories.
116    pub categories: Option<Vec<String>>,
117    /// Client-side support.
118    pub client_side: Option<String>,
119    /// Server-side support.
120    pub server_side: Option<String>,
121}
122
123impl ProjectInfo for SearchHit {
124    fn get_id(&self) -> &str { &self.project_id }
125    fn get_slug(&self) -> Option<&str> { self.slug.as_deref() }
126    fn get_title(&self) -> Option<&str> { self.title.as_deref() }
127    fn get_description(&self) -> Option<&str> { self.description.as_deref() }
128    fn get_categories(&self) -> Option<&[String]> { self.categories.as_deref() }
129    fn get_client_side(&self) -> Option<&str> { self.client_side.as_deref() }
130    fn get_server_side(&self) -> Option<&str> { self.server_side.as_deref() }
131    fn get_project_type(&self) -> &str { &self.project_type }
132    fn get_downloads(&self) -> i32 { self.downloads }
133    fn get_versions(&self) -> &[String] { &self.versions }
134    fn get_followers(&self) -> i32 { self.follows }
135    fn get_author(&self) -> &str { &self.author }
136    fn get_date_created(&self) -> &str { &self.date_created }
137    fn get_date_modified(&self) -> &str { &self.date_modified }
138}
139
140#[derive(Debug, Serialize, Deserialize)]
141pub struct SearchResult {
142    pub hits: Vec<SearchHit>,
143    pub offset: i32,
144    pub limit: i32,
145    pub total_hits: i32,
146}
147
148#[derive(Debug, Serialize, Deserialize)]
149pub struct Version {
150    pub id: String,
151    pub project_id: String,
152    pub author_id: String,
153    pub date_published: String,
154    pub downloads: i32,
155    pub files: Vec<VersionFile>,
156    pub name: Option<String>,
157    pub version_number: Option<String>,
158    pub changelog: Option<String>,
159    pub dependencies: Option<Vec<VersionDependency>>,
160    pub game_versions: Option<Vec<String>>,
161    pub version_type: Option<String>,
162    pub loaders: Option<Vec<String>>,
163    pub featured: Option<bool>,
164}
165
166#[derive(Debug, Serialize, Deserialize)]
167pub struct VersionFile {
168    pub hashes: Hashes,
169    pub url: String,
170    pub filename: String,
171    pub primary: bool,
172    pub size: i32,
173}
174
175#[derive(Debug, Serialize, Deserialize)]
176pub struct Hashes {
177    pub sha512: String,
178    pub sha1: String,
179}
180
181#[derive(Debug, Serialize, Deserialize)]
182pub struct Dependencies {
183    pub projects: Vec<Project>,
184    pub versions: Vec<Version>,
185}
186
187#[derive(Debug, Serialize, Deserialize)]
188pub struct VersionDependency {
189    pub dependency_type: String,
190    pub version_id: Option<String>,
191    pub project_id: Option<String>,
192    pub file_name: Option<String>,
193}
194