game_manager_lib/commands/
launcher.rs1use crate::commands::games::get_game_by_id;
2use crate::database::AppState;
3use crate::errors::AppError;
4use crate::utils::launcher::{resolve_launch, LaunchResolution};
5use serde::Serialize;
6use std::process::Command;
7use tauri::{AppHandle, Manager};
8use tauri_plugin_opener::OpenerExt;
9
10#[derive(Debug, Serialize)]
11#[serde(tag = "kind", rename_all = "camelCase")]
12pub enum LaunchOutcome {
13 Launched,
14 OpenedLauncher { installed: bool },
15 OpenedStore,
16 Unavailable,
17}
18
19#[tauri::command]
20pub async fn launch_game(
21 app: AppHandle,
22 game_id: String,
23 launcher_path_override: Option<String>,
24) -> Result<LaunchOutcome, AppError> {
25 let state = app.state::<AppState>();
26 let game = get_game_by_id(state, game_id.clone())?
27 .ok_or_else(|| AppError::NotFound(format!("Jogo não encontrado: {game_id}")))?;
28
29 match resolve_launch(&game, launcher_path_override.as_deref()) {
30 LaunchResolution::Protocol(url) => {
31 app.opener()
32 .open_url(url, None::<&str>)
33 .map_err(|e| AppError::LaunchError(e.to_string()))?;
34 Ok(LaunchOutcome::Launched)
35 }
36 LaunchResolution::Executable(path) => {
37 Command::new(&path).spawn()?; Ok(LaunchOutcome::Launched)
39 }
40 LaunchResolution::Launcher(path) => {
41 Command::new(&path).spawn()?;
42 Ok(LaunchOutcome::OpenedLauncher {
43 installed: game.installed,
44 })
45 }
46 LaunchResolution::Store(url) => {
47 app.opener()
48 .open_url(url, None::<&str>)
49 .map_err(|e| AppError::LaunchError(e.to_string()))?;
50 Ok(LaunchOutcome::OpenedStore)
51 }
52 LaunchResolution::Unavailable => Ok(LaunchOutcome::Unavailable),
53 }
54}