retrom_plugin_installer/
lib.rs

1use tauri::{
2    plugin::{Builder, TauriPlugin},
3    Manager, Runtime,
4};
5
6mod desktop;
7
8mod commands;
9mod error;
10
11pub use error::{Error, Result};
12
13use desktop::Installer;
14use tracing::{info_span, Instrument};
15
16/// Extensions to [`tauri::App`], [`tauri::AppHandle`] and [`tauri::Window`] to access the installer APIs.
17pub trait InstallerExt<R: Runtime> {
18    fn installer(&self) -> &Installer<R>;
19}
20
21impl<R: Runtime, T: Manager<R>> crate::InstallerExt<R> for T {
22    fn installer(&self) -> &Installer<R> {
23        self.state::<Installer<R>>().inner()
24    }
25}
26
27/// Initializes the plugin.
28#[tracing::instrument]
29pub fn init<R: Runtime>() -> TauriPlugin<R> {
30    Builder::<R>::new("installer")
31        .invoke_handler(tauri::generate_handler![
32            commands::install_game,
33            commands::uninstall_game,
34            commands::get_installation_status,
35            commands::subscribe_to_installation_index,
36            commands::subscribe_to_installation_updates,
37            commands::unsubscribe_from_installation_index,
38            commands::unsubscribe_from_installation_updates,
39            commands::open_installation_dir,
40            commands::migrate_installation_dir,
41            commands::abort_installation,
42            commands::clear_installation_dir,
43            commands::update_steam_installations
44        ])
45        .setup(|app, api| {
46            let installer = desktop::init(app, api)?;
47            app.manage::<Installer<R>>(installer);
48
49            let app = app.clone();
50            let (tx, rx) = std::sync::mpsc::channel::<crate::Result<()>>();
51
52            tauri::async_runtime::spawn_blocking(|| {
53                tauri::async_runtime::block_on(
54                    async move {
55                        let installer = app.installer();
56                        let res = installer.init_installation_index().await;
57
58                        tx.send(res).unwrap();
59                    }
60                    .instrument(info_span!("installer_setup")),
61                )
62            });
63
64            if let Err(why) = rx.recv().expect("Failed to receive from channel") {
65                tracing::error!("Failed to initialize installer: {:#?}", why);
66            }
67
68            Ok(())
69        })
70        .build()
71}