chore: add package bindings

This commit is contained in:
emirsassan 2025-07-15 21:34:23 +03:00
parent d98a3aedcf
commit 2593b293de
4 changed files with 48 additions and 9 deletions

View file

@ -10,7 +10,7 @@ mod modrinth;
pub use modrinth::ModrinthProviderImpl; pub use modrinth::ModrinthProviderImpl;
#[async_trait::async_trait(?Send)] #[async_trait::async_trait]
pub trait ProviderExt { pub trait ProviderExt {
async fn search(&self, query: &SearchQuery) -> LauncherResult<Paginated<ManagedPackage>>; async fn search(&self, query: &SearchQuery) -> LauncherResult<Paginated<ManagedPackage>>;
async fn get(&self, slug: &str) -> LauncherResult<ManagedPackage>; async fn get(&self, slug: &str) -> LauncherResult<ManagedPackage>;
@ -42,7 +42,7 @@ pub trait ProviderExt {
async fn get_versions(&self, slugs: &[String]) -> LauncherResult<Vec<ManagedVersion>>; async fn get_versions(&self, slugs: &[String]) -> LauncherResult<Vec<ManagedVersion>>;
} }
#[async_trait::async_trait(?Send)] #[async_trait::async_trait]
impl ProviderExt for Provider { impl ProviderExt for Provider {
async fn search(&self, query: &SearchQuery) -> LauncherResult<Paginated<ManagedPackage>> { async fn search(&self, query: &SearchQuery) -> LauncherResult<Paginated<ManagedPackage>> {
match self { match self {

View file

@ -37,7 +37,7 @@ impl ModrinthProviderImpl {
} }
} }
#[async_trait::async_trait(?Send)] #[async_trait::async_trait]
impl ProviderExt for ModrinthProviderImpl { impl ProviderExt for ModrinthProviderImpl {
async fn search(&self, query: &SearchQuery) -> LauncherResult<Paginated<ManagedPackage>> { async fn search(&self, query: &SearchQuery) -> LauncherResult<Paginated<ManagedPackage>> {
let mut url = Url::parse(url!("/search"))?; let mut url = Url::parse(url!("/search"))?;

View file

@ -1,8 +1,8 @@
use interpulse::api::minecraft::Version; use interpulse::api::minecraft::Version;
use onelauncher_entity::{clusters, icon::Icon, loader::GameLoader, package::Provider, prelude::entity, resolution::Resolution}; use onelauncher_entity::{clusters, icon::Icon, loader::GameLoader, package::Provider, packages, prelude::entity, resolution::Resolution};
use sea_orm::ActiveValue::Set; use sea_orm::ActiveValue::Set;
use serde::Serialize; use serde::Serialize;
use crate::{api::packages::data::{ManagedPackage, ManagedUser, ManagedVersion, SearchQuery}, store::{Settings, State}, utils::pagination::Paginated}; use crate::{api::packages::{data::{ManagedPackage, ManagedUser, ManagedVersion, SearchQuery}, provider::ProviderExt}, store::{Settings, State}, utils::pagination::Paginated};
use tauri::{AppHandle, Runtime}; use tauri::{AppHandle, Runtime};
use crate::{api::{self, cluster::dao::ClusterId}, error::{LauncherError, LauncherResult}, store::{credentials::MinecraftCredentials, Core}}; use crate::{api::{self, cluster::dao::ClusterId}, error::{LauncherError, LauncherResult}, store::{credentials::MinecraftCredentials, Core}};
@ -97,6 +97,9 @@ pub trait TauriLauncherApi {
#[taurpc(alias = "getPackageUser")] #[taurpc(alias = "getPackageUser")]
async fn get_package_user(provider: Provider, slug: String) -> LauncherResult<ManagedUser>; async fn get_package_user(provider: Provider, slug: String) -> LauncherResult<ManagedUser>;
#[taurpc(alias = "downloadPackage")]
async fn download_package(provider: Provider, package_id: String, version_id: String, cluster_id: ClusterId, skip_compatibility: Option<bool>) -> LauncherResult<packages::Model>;
} }
@ -387,4 +390,40 @@ impl TauriLauncherApi for TauriLauncherApiImpl {
} }
// Packages // Packages
async fn search_packages(self, provider: Provider, query: SearchQuery) -> LauncherResult<Paginated<ManagedPackage>> {
Ok(provider.search(&query).await?)
}
async fn get_package(self, provider: Provider, slug: String) -> LauncherResult<ManagedPackage> {
Ok(provider.get(&slug).await?)
}
async fn get_multiple_packages(self, provider: Provider, slugs: Vec<String>) -> LauncherResult<Vec<ManagedPackage>> {
Ok(provider.get_multiple(&slugs).await?)
}
async fn get_package_versions(self, provider: Provider, slug: String, mc_versions: Option<Vec<String>>, loaders: Option<Vec<GameLoader>>, offset: usize, limit: usize) -> LauncherResult<Paginated<ManagedVersion>> {
Ok(provider.get_versions_paginated(&slug, mc_versions, loaders, offset, limit).await?)
}
async fn get_package_user(self, provider: Provider, slug: String) -> LauncherResult<ManagedUser> {
Ok(provider.get_user(&slug).await?)
}
async fn download_package(self, provider: Provider, package_id: String, version_id: String, cluster_id: ClusterId, skip_compatibility: Option<bool>) -> LauncherResult<packages::Model> {
let cluster = api::cluster::dao::get_cluster_by_id(cluster_id).await?
.ok_or_else(|| anyhow::anyhow!("cluster with id {} not found", cluster_id))?;
let package = provider.get(&package_id).await?;
let versions = provider.get_versions(&[version_id]).await?;
let version = versions.into_iter().next()
.ok_or_else(|| anyhow::anyhow!("Version not found"))?;
let model = api::packages::download_package(&package, &version, None).await?;
api::packages::link_package(&model, &cluster, skip_compatibility).await?;
Ok(model)
}
} }

View file

@ -1,18 +1,18 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::marker::Send;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[onelauncher_macro::specta] #[onelauncher_macro::specta]
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct Paginated<T> pub struct Paginated<T>
where T: Clone + Serialize { where T: Clone + Serialize + Send {
pub total: usize, pub total: usize,
pub offset: usize, pub offset: usize,
pub limit: usize, pub limit: usize,
pub items: Vec<T>, pub items: Vec<T>,
} }
impl<T: Clone + Serialize> Debug for Paginated<T> { impl<T: Clone + Serialize + Send> Debug for Paginated<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Paginated") f.debug_struct("Paginated")
.field("total", &self.total) .field("total", &self.total)
@ -23,7 +23,7 @@ impl<T: Clone + Serialize> Debug for Paginated<T> {
} }
} }
impl <T: Clone + Serialize> Paginated<T> { impl <T: Clone + Serialize + Send> Paginated<T> {
#[must_use] #[must_use]
pub const fn new(total: usize, offset: usize, limit: usize, items: Vec<T>) -> Self { pub const fn new(total: usize, offset: usize, limit: usize, items: Vec<T>) -> Self {
Self { total, offset, limit, items } Self { total, offset, limit, items }