Skip to main content

ferinth/structures/
project.rs

1//! Models related to projects
2//!
3//! [documentation](https://docs.modrinth.com/api-spec/#tag/project_model)
4
5use super::*;
6
7#[derive(Deserialize, Serialize, Debug, Clone)]
8pub struct Project {
9    /// The project's slug, used for vanity URLs.
10    /// This can change at any time, so use the [`Self::id`] for long term storage.
11    pub slug: String,
12    pub title: String,
13    /// A short description of the project
14    pub description: String,
15    pub categories: Vec<String>,
16    pub client_side: SideType,
17    pub server_side: SideType,
18    /// A long form description of the project
19    pub body: String,
20    pub status: ProjectStatus,
21    /// The status requested. Only visible to those with appropriate permissions
22    pub requested_status: Option<RequestedStatus>,
23    /// A list of categories which are searchable but non-primary
24    pub additional_categories: Vec<String>,
25    /// A link to submit bugs or issues with the project
26    #[serde(deserialize_with = "deserialise_optional_url")]
27    pub issues_url: Option<Url>,
28    /// A link to the project's source code
29    #[serde(deserialize_with = "deserialise_optional_url")]
30    pub source_url: Option<Url>,
31    /// A link to the project's wiki page or other relevant information
32    #[serde(deserialize_with = "deserialise_optional_url")]
33    pub wiki_url: Option<Url>,
34    /// The project's Discord server invite
35    #[serde(deserialize_with = "deserialise_optional_url")]
36    pub discord_url: Option<Url>,
37    pub donation_urls: Vec<DonationLink>,
38    pub project_type: ProjectType,
39    pub downloads: Int,
40    #[serde(deserialize_with = "deserialise_optional_url")]
41    pub icon_url: Option<Url>,
42    /// The RGB color of the project, automatically generated from the project icon
43    pub color: Option<Int>,
44    /// The ID of the moderation thread associated with this project
45    pub thread_id: ID,
46    pub monetization_status: MonetizationStatus,
47    pub id: ID,
48    /// The ID of the team that has ownership of this project
49    pub team: ID,
50    pub published: UtcTime,
51    pub updated: UtcTime,
52    /// The date the project's status was approved
53    pub approved: Option<UtcTime>,
54    pub queued: Option<UtcTime>,
55    pub followers: Int,
56    pub license: License,
57    /// A list of the version IDs of the project.
58    /// This will only ever be empty if the project is a draft.
59    pub versions: Vec<ID>,
60    /// A list of all of the game versions supported by the project
61    pub game_versions: Vec<String>,
62    /// A list of all of the loaders supported by the project
63    pub loaders: Vec<String>,
64    /// A list of images that have been uploaded to the project's gallery
65    pub gallery: Vec<GalleryItem>,
66    // The ID of the organisation that owns this project
67    pub organization: Option<ID>,
68}
69
70#[derive(Deserialize, Serialize, Debug, Clone)]
71pub struct License {
72    /// The SPDX license ID of a project
73    pub id: String,
74    pub name: String,
75    /// The URL to this license
76    #[serde(deserialize_with = "deserialise_optional_url")]
77    pub url: Option<Url>,
78}
79
80#[derive(Deserialize, Serialize, Debug, Clone)]
81pub struct DonationLink {
82    /// The donation platform's ID
83    pub id: String,
84    pub platform: String,
85    /// A link to the donation platform and user
86    pub url: Url,
87}
88
89/// An image that have been uploaded to a project's gallery
90#[derive(Serialize, Deserialize, Debug, Clone)]
91pub struct GalleryItem {
92    pub url: Url,
93    pub raw_url: Url,
94    pub featured: bool,
95    pub title: Option<String>,
96    pub description: Option<String>,
97    pub created: UtcTime,
98    /// The order of the gallery image.
99    /// Gallery images are sorted by this field and then alphabetically by title.
100    pub ordering: isize,
101}
102
103#[derive(Serialize, Deserialize, Debug, Clone)]
104pub struct ProjectDependencies {
105    pub projects: Vec<Project>,
106    pub versions: Vec<version::Version>,
107}
108
109/// Fields to edit on the projects specified
110#[derive(Serialize, Deserialize, Debug, Clone)]
111pub struct EditMultipleProjectsBody {
112    /// Set all of the categories to the categories specified here
113    pub categories: Vec<String>,
114    /// Add all of the categories specified here
115    pub add_categories: Vec<String>,
116    /// Remove all of the categories specified here
117    pub remove_categories: Vec<String>,
118    /// Set all of the additional categories to the categories specified here
119    pub additional_categories: Vec<String>,
120    /// Add all of the additional categories specified here
121    pub add_additional_categories: Vec<String>,
122    /// Remove all of the additional categories specified here
123    pub remove_additional_categories: Vec<String>,
124    /// Set all of the donation links to the donation links specified here
125    pub donation_urls: Vec<DonationLink>,
126    /// Add all of the donation links specified here
127    pub add_donation_urls: Vec<DonationLink>,
128    /// Remove all of the donation links specified here
129    pub remove_donation_urls: Vec<DonationLink>,
130    /// A link to where to submit bugs or issues with the projects
131    pub issues_url: Option<String>,
132    /// A link to the source code of the projects
133    pub source_url: Option<String>,
134    /// A link to the projects' wiki page or other relevant information
135    pub wiki_url: Option<String>,
136    /// An optional invite link to the projects' discord
137    pub discord_url: Option<String>,
138}
139
140#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
141#[serde(rename_all = "lowercase")]
142pub enum ProjectStatus {
143    Approved,
144    Archived,
145    /// A moderator's message should be available in the project struct
146    Rejected,
147    Draft,
148    /// The project has been approved and is publicly accessible, but will not show up in search results
149    Unlisted,
150    /// The project has been submitted for approval and is being reviewed
151    Processing,
152    Withheld,
153    /// The project's status has been scheduled to change.
154    /// Check the project's `requested_status` for more information.
155    Scheduled,
156    Private,
157    #[serde(other)]
158    Unknown,
159}
160
161#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
162#[serde(rename_all = "lowercase")]
163pub enum RequestedStatus {
164    Approved,
165    Archived,
166    Unlisted,
167    Private,
168    Draft,
169    #[serde(other)]
170    Other,
171}
172
173#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
174#[serde(rename_all = "kebab-case")]
175pub enum MonetizationStatus {
176    Monetized,
177    Demonetized,
178    ForceDemonetized,
179    #[serde(other)]
180    Other,
181}
182
183pub type ProjectSupportRange = SideType;
184#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
185#[serde(rename_all = "lowercase")]
186pub enum SideType {
187    /// The mod is required on this side to function
188    Required,
189    /// The mod is not required on this side to function.
190    /// However, functionality might be enhanced if it is present.
191    Optional,
192    /// The mod will not run on this side
193    Unsupported,
194    /// It is unknown if the project will run on this side
195    Unknown,
196}
197
198#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)]
199#[serde(rename_all = "snake_case")]
200pub enum ProjectType {
201    Mod,
202    Modpack,
203    Resourcepack,
204    Shader,
205    Plugin,
206    Datapack,
207    MinecraftJavaServer,
208    #[serde(other)]
209    Other,
210}
211
212/// File extensions for images
213#[derive(Debug, Clone, Copy, PartialEq, Eq)]
214pub enum ImageFileExt {
215    /// [Portable Network Graphics](https://en.wikipedia.org/wiki/PNG)
216    PNG,
217    /// [Joint Photographic Experts Group](https://en.wikipedia.org/wiki/JPEG)
218    JPG,
219    /// [Joint Photographic Experts Group](https://en.wikipedia.org/wiki/JPEG)
220    JPEG,
221    /// [Bitmap](https://en.wikipedia.org/wiki/BMP_file_format)
222    BMP,
223    /// [Graphics Interchange Format](https://en.wikipedia.org/wiki/GIF)
224    GIF,
225    /// [Web Picture](https://en.wikipedia.org/wiki/WebP)
226    WebP,
227    /// [Scalable Vector Graphics](https://en.wikipedia.org/wiki/SVG)
228    SVG,
229    /// [Scalable Vector Graphics](https://en.wikipedia.org/wiki/SVG#Compression) (gZip compressed)
230    SVGZ,
231    /// [Silicon Graphics Image](https://en.wikipedia.org/wiki/Silicon_Graphics_Image)
232    RGB,
233}
234
235impl std::fmt::Display for ImageFileExt {
236    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237        write!(f, "{}", format!("{:?}", self).to_lowercase())
238    }
239}