conduit_cli/core/api/modrinth/
mod.rs1pub mod models;
2
3use crate::errors::{ConduitError, ConduitResult};
4
5use self::models::{ProjectResponse, VersionResponse};
6use reqwest::Client;
7
8pub struct ModrinthClient {
9 client: Client,
10}
11
12impl Default for ModrinthClient {
13 fn default() -> Self {
14 Self {
15 client: Client::builder()
16 .user_agent("conduit-cli (github.com/SirCesarium/conduit-cli)")
17 .build()
18 .unwrap(),
19 }
20 }
21}
22
23impl ModrinthClient {
24 pub async fn get_project(&self, id: &str) -> ConduitResult<ProjectResponse> {
25 let url = format!("https://api.modrinth.com/v2/project/{id}");
26 let response = self.client.get(url).send().await?;
27
28 if response.status() == 404 {
29 return Err(ConduitError::NotFound(id.to_string()));
30 }
31
32 let project = response.json::<ProjectResponse>().await?;
33 Ok(project)
34 }
35
36 pub async fn get_version(&self, version_id: &str) -> ConduitResult<VersionResponse> {
37 let url = format!("https://api.modrinth.com/v2/version/{version_id}");
38 let response = self.client.get(url).send().await?;
39
40 if response.status() == 404 {
41 return Err(ConduitError::NotFound(version_id.to_string()));
42 }
43
44 let version = response.json::<VersionResponse>().await?;
45 Ok(version)
46 }
47
48 pub async fn get_project_versions(
49 &self,
50 id_or_slug: &str,
51 loaders: &[String],
52 game_versions: &[String],
53 ) -> ConduitResult<Vec<VersionResponse>> {
54 let loaders_query = serde_json::to_string(loaders).unwrap();
55 let versions_query = serde_json::to_string(game_versions).unwrap();
56
57 let url = format!(
58 "https://api.modrinth.com/v2/project/{id_or_slug}/version?loaders={loaders_query}&game_versions={versions_query}"
59 );
60
61 let response = self.client.get(url).send().await?;
62
63 if response.status() == 404 {
64 return Err(ConduitError::NotFound(id_or_slug.to_string()));
65 }
66
67 let versions = response.json::<Vec<VersionResponse>>().await?;
68 Ok(versions)
69 }
70}