269 lines
6.2 KiB
Rust
269 lines
6.2 KiB
Rust
//! Proxy for Tauri/CLI specific features and communication
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
use std::path::PathBuf;
|
|
use std::sync::Arc;
|
|
use tokio::sync::{OnceCell, RwLock};
|
|
use uuid::Uuid;
|
|
|
|
use crate::store::{ClusterPath, IngressProcessor};
|
|
|
|
pub mod send;
|
|
pub mod utils;
|
|
pub use utils::*;
|
|
|
|
static PROXY_STATE: OnceCell<Arc<ProxyState>> = OnceCell::const_new();
|
|
pub struct ProxyState {
|
|
#[cfg(feature = "tauri")]
|
|
pub app: tauri::AppHandle<tauri::Wry>,
|
|
pub ingress_feeds: RwLock<HashMap<Uuid, Ingress>>,
|
|
}
|
|
|
|
#[derive(Serialize, Debug, Clone)]
|
|
pub struct Ingress {
|
|
pub ingress_uuid: Uuid,
|
|
pub message: String,
|
|
pub ingress_type: IngressType,
|
|
pub total: f64,
|
|
pub current: f64,
|
|
#[serde(skip)]
|
|
pub last_sent: f64,
|
|
#[cfg(feature = "cli")]
|
|
#[serde(skip)]
|
|
pub cli: indicatif::ProgressBar,
|
|
}
|
|
|
|
#[derive(Serialize, Debug, Clone)]
|
|
pub struct IngressId(Uuid);
|
|
|
|
impl Drop for IngressId {
|
|
fn drop(&mut self) {
|
|
let ingress_uuid = self.0;
|
|
tokio::spawn(async move {
|
|
if let Ok(proxy_state) = ProxyState::get().await {
|
|
let mut ingress_feeds = proxy_state.ingress_feeds.write().await;
|
|
#[cfg(any(feature = "tauri", feature = "cli"))]
|
|
if let Some(ingress) = ingress_feeds.remove(&ingress_uuid) {
|
|
#[cfg(feature = "cli")]
|
|
{
|
|
let cli = ingress.cli;
|
|
cli.finish();
|
|
}
|
|
|
|
#[cfg(feature = "tauri")]
|
|
{
|
|
let _ingress_feed_uuid = ingress.ingress_uuid;
|
|
let event = ingress.ingress_type.clone();
|
|
let fraction = ingress.current / ingress.total;
|
|
|
|
use tauri::Emitter;
|
|
let _ = proxy_state.app.emit(
|
|
"ingress",
|
|
IngressPayload {
|
|
fraction: None,
|
|
message: "Complete".to_string(),
|
|
event,
|
|
ingress_uuid,
|
|
},
|
|
);
|
|
|
|
tracing::trace!("exited at {fraction} for ingress: {:?}", ingress_uuid);
|
|
}
|
|
}
|
|
|
|
#[cfg(not(any(feature = "tauri", feature = "cli")))]
|
|
ingress_feeds.remove(&ingress_uuid);
|
|
}
|
|
|
|
if crate::State::initalized() {
|
|
let _ = IngressProcessor::finish(
|
|
crate::store::IngressProcessType::IngressFeed,
|
|
ingress_uuid,
|
|
)
|
|
.await;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
impl ProxyState {
|
|
#[cfg(feature = "tauri")]
|
|
pub async fn initialize(handle: &tauri::AppHandle<tauri::Wry>) -> crate::Result<Arc<Self>> {
|
|
PROXY_STATE
|
|
.get_or_try_init(|| async {
|
|
Ok(Arc::new(Self {
|
|
app: handle.clone(),
|
|
ingress_feeds: RwLock::new(HashMap::new()),
|
|
}))
|
|
})
|
|
.await
|
|
.cloned()
|
|
}
|
|
|
|
#[cfg(not(feature = "tauri"))]
|
|
pub async fn initialize() -> crate::Result<Arc<Self>> {
|
|
PROXY_STATE
|
|
.get_or_try_init(|| async {
|
|
Ok(Arc::new(Self {
|
|
ingress_feeds: RwLock::new(HashMap::new()),
|
|
}))
|
|
})
|
|
.await
|
|
.cloned()
|
|
}
|
|
|
|
#[cfg(feature = "tauri")]
|
|
pub async fn get_main_window() -> crate::Result<tauri::WebviewWindow> {
|
|
use tauri::Manager;
|
|
let value = Self::get().await?;
|
|
Ok(value.app.get_webview_window("main").unwrap())
|
|
}
|
|
|
|
#[cfg(feature = "tauri")]
|
|
pub async fn get() -> crate::Result<Arc<Self>> {
|
|
Ok(PROXY_STATE.get().ok_or(ProxyError::NotInitialized)?.clone())
|
|
}
|
|
|
|
#[cfg(not(feature = "tauri"))]
|
|
pub async fn get() -> crate::Result<Arc<Self>> {
|
|
Self::initialize().await
|
|
}
|
|
|
|
pub async fn list_ingress_feeds() -> crate::Result<HashMap<Uuid, Ingress>> {
|
|
let value = Self::get().await?;
|
|
let read = value.ingress_feeds.read().await;
|
|
|
|
let mut display_list: HashMap<Uuid, Ingress> = HashMap::new();
|
|
for (uuid, ingress) in read.iter() {
|
|
display_list.insert(*uuid, ingress.clone());
|
|
}
|
|
|
|
Ok(display_list)
|
|
}
|
|
}
|
|
|
|
#[cfg_attr(feature = "specta", derive(specta::Type))]
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq)]
|
|
#[serde(tag = "type")]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum IngressType {
|
|
Initialize,
|
|
DownloadJava {
|
|
version: u32,
|
|
},
|
|
DownloadLoader {
|
|
cluster_path: PathBuf,
|
|
cluster_name: String,
|
|
},
|
|
SyncCluster {
|
|
cluster_path: PathBuf,
|
|
cluster_name: String,
|
|
},
|
|
CopyCluster {
|
|
import: PathBuf,
|
|
cluster_name: String,
|
|
},
|
|
SyncConfig {
|
|
new_path: PathBuf,
|
|
},
|
|
Archival {
|
|
cluster_path: PathBuf,
|
|
cluster_name: String,
|
|
},
|
|
DownloadPackage {
|
|
cluster_path: PathBuf,
|
|
package_name: String,
|
|
icon: Option<PathBuf>,
|
|
package_id: Option<String>,
|
|
package_version: Option<String>,
|
|
},
|
|
DownloadPack {
|
|
cluster_path: PathBuf,
|
|
package_name: String,
|
|
icon: Option<String>,
|
|
package_version: String,
|
|
},
|
|
}
|
|
|
|
#[cfg_attr(feature = "tauri", derive(specta::Type, tauri_specta::Event))]
|
|
#[derive(Serialize, Clone)]
|
|
pub struct IngressPayload {
|
|
pub event: IngressType,
|
|
pub ingress_uuid: Uuid,
|
|
pub fraction: Option<f64>,
|
|
pub message: String,
|
|
}
|
|
|
|
#[cfg_attr(feature = "tauri", derive(specta::Type, tauri_specta::Event))]
|
|
#[derive(Serialize, Clone)]
|
|
pub struct OfflinePayload {
|
|
pub offline: bool,
|
|
}
|
|
|
|
#[cfg_attr(feature = "tauri", derive(specta::Type, tauri_specta::Event))]
|
|
#[derive(Serialize, Clone)]
|
|
pub struct MessagePayload {
|
|
pub message: String,
|
|
}
|
|
|
|
#[cfg_attr(feature = "tauri", derive(specta::Type, tauri_specta::Event))]
|
|
#[derive(Serialize, Clone)]
|
|
#[serde(tag = "event")]
|
|
pub enum InternetPayload {
|
|
InstallPackage { id: String },
|
|
InstallPack { id: String },
|
|
InstallPath { path: PathBuf },
|
|
}
|
|
|
|
#[cfg_attr(feature = "tauri", derive(specta::Type, tauri_specta::Event))]
|
|
#[derive(Serialize, Clone)]
|
|
pub struct ProcessPayload {
|
|
pub uuid: Uuid,
|
|
pub pid: u32,
|
|
pub event: ProcessPayloadType,
|
|
pub message: String,
|
|
}
|
|
|
|
#[cfg_attr(feature = "specta", derive(specta::Type))]
|
|
#[derive(Serialize, Clone, Debug)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum ProcessPayloadType {
|
|
Started,
|
|
Modified,
|
|
Finished,
|
|
Logging,
|
|
}
|
|
|
|
#[cfg_attr(feature = "tauri", derive(specta::Type, tauri_specta::Event))]
|
|
#[derive(Serialize, Clone)]
|
|
pub struct ClusterPayload {
|
|
pub uuid: Uuid,
|
|
pub cluster_path: ClusterPath,
|
|
pub path: PathBuf,
|
|
pub name: String,
|
|
pub event: ClusterPayloadType,
|
|
}
|
|
|
|
#[cfg_attr(feature = "specta", derive(specta::Type))]
|
|
#[derive(Serialize, Clone)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum ClusterPayloadType {
|
|
Created,
|
|
Inserted,
|
|
Synced,
|
|
Edited,
|
|
Deleted,
|
|
}
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum ProxyError {
|
|
#[error("event state was not initialized!")]
|
|
NotInitialized,
|
|
|
|
#[error("non-existant ingress of key: {0}")]
|
|
NoIngressFound(Uuid),
|
|
|
|
#[cfg(feature = "tauri")]
|
|
#[error("Tauri error: {0}")]
|
|
TauriError(#[from] tauri::Error),
|
|
}
|