Skip to main content

conduit_cli/core/api/modrinth/
mod.rs

1pub 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}