Skip to content

Commit 8b0503e

Browse files
committed
feat(versions): implement get_project_version function (Retrieves a project version with custom filtering)
feat(versions): add tests related with get_project_version func chore(versions): docstring changes
1 parent e830092 commit 8b0503e

1 file changed

Lines changed: 82 additions & 37 deletions

File tree

src/api/versions.rs

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,20 @@ use crate::{
77
};
88

99
impl ModrinthAPI {
10-
/// Retrieves a list of project versions, optionally filtered, or a single specific version.
10+
/// Retrieves a list of project versions with custom filtering.
1111
///
1212
/// # Arguments
1313
/// * `project_id` - Project slug/id (`&str`).
14-
/// * `extra_options` - `Option<ExtraOptions<'_>>`: Optional parameters to filter the list of versions
14+
/// * `extra_options` - `Option<ProjectVersionsFilter<'_>>` ([`ProjectVersionsFilter`]): Optional parameters to filter the list of versions
1515
/// or to retrieve a specific version.
1616
///
1717
/// If `extra_options` is `None`, all versions for the project will be returned without any filters.
1818
///
19-
/// Fields of `ExtraOptions`:
20-
///
21-
/// - `loaders`: `Option<&[&str]>` - A slice of loader IDs (e.g., `&["forge", "fabric"]`)
22-
/// to filter the list of versions. This is only applied if `number` is `None`.
23-
/// Example: `loaders: Some(&["fabric", "quilt"])`
24-
///
25-
/// - `game_versions`: `Option<&[&str]>` - A slice of game version IDs (e.g., `&["1.19.2", "1.20.1"]`)
26-
/// to filter the list of versions. This is only applied if `number` is `None`.
27-
/// Example: `game_versions: Some(&["1.20.1"])`
28-
///
29-
/// - `featured`: `Option<bool>` - If `Some(true)`, only featured versions will be returned.
30-
/// If `Some(false)`, featured versions will be excluded. If `None`, both featured and
31-
/// non-featured versions are included. This is only applied if `number` is `None`.
32-
/// Example: `featured: Some(true)`
33-
///
3419
/// Example usage of `extra_options`:
3520
/// ```no_run
36-
/// # use modrinth_api::structs::versions::ExtraOptions;
37-
/// let options_for_filtered_list = ExtraOptions {
21+
/// use modrinth_api::structs::versions::ProjectVersionsFilter;
22+
///
23+
/// let options_for_filtered_list = ProjectVersionsFilter {
3824
/// loaders: Some(&["fabric"]),
3925
/// game_versions: Some(&["1.20.1"]),
4026
/// featured: Some(true),
@@ -49,7 +35,7 @@ impl ModrinthAPI {
4935
pub async fn get_project_versions(
5036
&self,
5137
project_id: &str,
52-
extra_options: Option<ExtraOptions<'_>>,
38+
extra_options: Option<ProjectVersionsFilter<'_>>,
5339
) -> Result<Vec<Version>> {
5440
check_id_slug(&[project_id])?;
5541

@@ -81,35 +67,64 @@ impl ModrinthAPI {
8167
/// `Result<Version>`:
8268
/// - `Ok(Version)`: [`Version`] struct.
8369
/// - `Err(crate::error::Error)`: An error occurred during the API request or data processing.
84-
pub async fn get_version(&self, version_id: &str) -> Result<Version> {
70+
pub async fn get_version_by_id(&self, version_id: &str) -> Result<Version> {
8571
check_id_slug(&[version_id])?;
8672
self.client
8773
.get(BASE_URL.join_all(vec!["version", version_id]))
8874
.custom_send_json()
8975
.await
9076
}
9177

92-
//
93-
pub async fn version_list_filtered(
78+
/// Retrieves a project [`Version`] with custom filtering.
79+
///
80+
/// # Arguments
81+
/// * `project_id` - Project slug/id (`&str`).
82+
/// * `extra_options` - `Option<ProjectVersionParams<'_>>`: Optional parameters to filter the list of versions
83+
/// or to retrieve a specific version.
84+
///
85+
/// If `extra_options` is `None`, all versions for the project will be returned without any filters.
86+
///
87+
/// Example usage of `extra_options`:
88+
/// ```no_run
89+
/// use modrinth_api::structs::versions::ProjectVersionParams;
90+
///
91+
/// let options_for_filtered_list = ProjectVersionParams {
92+
/// number: Some("mc1.20.1-0.5.13-fabric"), // or Some("OihdIimA")
93+
/// loaders: Some(&["fabric"]),
94+
/// game_versions: Some(&["1.20.1"]),
95+
/// featured: Some(true),
96+
/// };
97+
/// ```
98+
///
99+
/// # Returns
100+
/// `Result<Vec<Version>>`:
101+
/// - `Ok(Vec<Version>)`: A list of the [`Version`] structs. If `number` was specified in `extra_options`,
102+
/// this vector will contain at most one [`Version`] struct.
103+
/// - `Err(crate::error::Error)`: An error occurred during the API request or data processing.
104+
pub async fn get_project_version(
94105
&self,
95106
project_id: &str,
96-
loaders: Option<&[&str]>,
97-
game_versions: Option<&[&str]>,
98-
featured: Option<bool>,
99-
) -> Result<Vec<Version>> {
107+
extra_options: Option<ProjectVersionParams<'_>>,
108+
) -> Result<Version> {
100109
check_id_slug(&[project_id])?;
110+
101111
let mut url = BASE_URL.join_all(vec!["project", project_id, "version"]);
102-
if let Some(loaders) = loaders {
103-
url = url.with_query_json("loaders", loaders)?;
104-
}
105-
if let Some(game_versions) = game_versions {
106-
url = url.with_query_json("game_versions", game_versions)?;
107-
}
108-
if let Some(featured) = featured {
109-
url = url.with_query_json("featured", featured)?;
112+
113+
match extra_options {
114+
Some(extra_options) => {
115+
url = BASE_URL.join_all(vec![
116+
"project",
117+
project_id,
118+
"version",
119+
extra_options.number.unwrap(),
120+
]);
121+
url = url.add_optional_query_json("loaders", extra_options.loaders)?;
122+
url = url.add_optional_query_json("game_versions", extra_options.game_versions)?;
123+
url = url.add_optional_query_json("featured", extra_options.featured)?;
124+
}
125+
None => {}
110126
}
111127

112-
println!("{url}");
113128
self.client.get(url).custom_send_json().await
114129
}
115130
}
@@ -132,7 +147,7 @@ mod tests {
132147
#[tokio::test]
133148
async fn get_version_from_project_extra() -> Result<()> {
134149
let api = ModrinthAPI::default();
135-
let options = ExtraOptions {
150+
let options = ProjectVersionsFilter {
136151
loaders: Some(&["fabric"]),
137152
game_versions: Some(&["1.20.1"]),
138153
featured: Some(true),
@@ -144,4 +159,34 @@ mod tests {
144159
assert!(result.unwrap().name.contains("Sodium")); // assume that is Sodium...
145160
Ok(())
146161
}
162+
163+
#[tokio::test]
164+
async fn get_single_version_from_project_extra() -> Result<()> {
165+
let api = ModrinthAPI::default();
166+
let options = ProjectVersionParams {
167+
number: Some("mc1.20.1-0.5.13-fabric"),
168+
loaders: Some(&["fabric"]),
169+
game_versions: Some(&["1.20.1"]),
170+
featured: Some(true),
171+
};
172+
let result = api.get_project_version("AANobbMI", Some(options)).await?;
173+
174+
assert!(result.name.contains("Sodium")); // assume that is Sodium...
175+
Ok(())
176+
}
177+
178+
#[tokio::test]
179+
async fn get_single_version_from_project_with_wrong_id() -> Result<()> {
180+
let api = ModrinthAPI::default();
181+
let options = ProjectVersionParams {
182+
number: Some("2"),
183+
loaders: Some(&["fabric"]),
184+
game_versions: Some(&["1.20.1"]),
185+
featured: Some(true),
186+
};
187+
let result = api.get_project_version("AANobbMI", Some(options)).await;
188+
189+
assert!(result.is_err());
190+
Ok(())
191+
}
147192
}

0 commit comments

Comments
 (0)