refactor(cmd): move switch-validation helper into new profile_switch module
This commit is contained in:
@@ -11,6 +11,7 @@ pub mod lightweight;
|
||||
pub mod media_unlock_checker;
|
||||
pub mod network;
|
||||
pub mod profile;
|
||||
mod profile_switch;
|
||||
pub mod proxy;
|
||||
pub mod runtime;
|
||||
pub mod save_profile;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::CmdResult;
|
||||
use super::StringifyErr;
|
||||
use super::profile_switch::validate_switch_request;
|
||||
use crate::{
|
||||
config::{
|
||||
Config, IProfiles, PrfItem, PrfOption,
|
||||
@@ -17,12 +18,11 @@ use crate::{
|
||||
};
|
||||
use futures::FutureExt;
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde_yaml_ng as serde_yaml;
|
||||
|
||||
use smartstring::alias::String;
|
||||
use std::{
|
||||
any::Any,
|
||||
collections::VecDeque,
|
||||
fs,
|
||||
panic::AssertUnwindSafe,
|
||||
sync::atomic::{AtomicBool, AtomicU64, Ordering},
|
||||
time::Duration,
|
||||
@@ -33,73 +33,6 @@ use tokio::sync::{
|
||||
oneshot,
|
||||
};
|
||||
|
||||
async fn validate_switch_request(task_id: u64, profile_id: &str) -> Result<(), String> {
|
||||
logging!(
|
||||
info,
|
||||
Type::Cmd,
|
||||
"Validating profile switch task {} -> {}",
|
||||
task_id,
|
||||
profile_id
|
||||
);
|
||||
|
||||
let profile_key: String = profile_id.into();
|
||||
let (file_path, profile_type, is_current, remote_url) = {
|
||||
let profiles_guard = Config::profiles().await;
|
||||
let latest = profiles_guard.latest_ref();
|
||||
let item = latest.get_item(&profile_key).map_err(|err| -> String {
|
||||
format!("Target profile {} not found: {}", profile_id, err).into()
|
||||
})?;
|
||||
(
|
||||
item.file.clone().map(|f| f.to_string()),
|
||||
item.itype.clone().map(|t| t.to_string()),
|
||||
latest
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|current| current.as_str() == profile_id)
|
||||
.unwrap_or(false),
|
||||
item.url.clone().map(|u| u.to_string()),
|
||||
)
|
||||
};
|
||||
|
||||
if is_current {
|
||||
logging!(
|
||||
info,
|
||||
Type::Cmd,
|
||||
"Switch task {} is targeting the current profile {}; skipping validation",
|
||||
task_id,
|
||||
profile_id
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if matches!(profile_type.as_deref(), Some("remote")) {
|
||||
let has_url = remote_url.as_ref().map(|u| !u.is_empty()).unwrap_or(false);
|
||||
if !has_url {
|
||||
return Err({
|
||||
let msg = format!("Remote profile {} is missing a download URL", profile_id);
|
||||
msg.into()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(file) = file_path {
|
||||
let profiles_dir = dirs::app_profiles_dir().map_err(|err| -> String {
|
||||
format!("Failed to resolve profiles directory: {}", err).into()
|
||||
})?;
|
||||
let path = profiles_dir.join(&file);
|
||||
|
||||
let contents = fs::read_to_string(&path).map_err(|err| -> String {
|
||||
format!("Failed to read profile file {}: {}", path.display(), err).into()
|
||||
})?;
|
||||
|
||||
serde_yaml::from_str::<serde_yaml::Value>(&contents).map_err(|err| -> String {
|
||||
format!("Profile YAML parse failed for {}: {}", path.display(), err).into()
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
static SWITCH_MUTEX: OnceCell<Mutex<()>> = OnceCell::new();
|
||||
static SWITCH_QUEUE: OnceCell<mpsc::Sender<SwitchDriverMessage>> = OnceCell::new();
|
||||
const SWITCH_QUEUE_CAPACITY: usize = 32;
|
||||
|
||||
76
src-tauri/src/cmd/profile_switch.rs
Normal file
76
src-tauri/src/cmd/profile_switch.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use crate::{
|
||||
config::Config,
|
||||
logging,
|
||||
utils::{dirs, logging::Type},
|
||||
};
|
||||
use serde_yaml_ng as serde_yaml;
|
||||
use smartstring::alias::String;
|
||||
use std::fs;
|
||||
|
||||
/// Validate profile switch request before queueing.
|
||||
pub async fn validate_switch_request(task_id: u64, profile_id: &str) -> Result<(), String> {
|
||||
logging!(
|
||||
info,
|
||||
Type::Cmd,
|
||||
"Validating profile switch task {} -> {}",
|
||||
task_id,
|
||||
profile_id
|
||||
);
|
||||
|
||||
let profile_key: String = profile_id.into();
|
||||
let (file_path, profile_type, is_current, remote_url) = {
|
||||
let profiles_guard = Config::profiles().await;
|
||||
let latest = profiles_guard.latest_ref();
|
||||
let item = latest.get_item(&profile_key).map_err(|err| -> String {
|
||||
format!("Target profile {} not found: {}", profile_id, err).into()
|
||||
})?;
|
||||
(
|
||||
item.file.clone().map(|f| f.to_string()),
|
||||
item.itype.clone().map(|t| t.to_string()),
|
||||
latest
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|current| current.as_str() == profile_id)
|
||||
.unwrap_or(false),
|
||||
item.url.clone().map(|u| u.to_string()),
|
||||
)
|
||||
};
|
||||
|
||||
if is_current {
|
||||
logging!(
|
||||
info,
|
||||
Type::Cmd,
|
||||
"Switch task {} is targeting the current profile {}; skipping validation",
|
||||
task_id,
|
||||
profile_id
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if matches!(profile_type.as_deref(), Some("remote")) {
|
||||
let has_url = remote_url.as_ref().map(|u| !u.is_empty()).unwrap_or(false);
|
||||
if !has_url {
|
||||
return Err({
|
||||
let msg = format!("Remote profile {} is missing a download URL", profile_id);
|
||||
msg.into()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(file) = file_path {
|
||||
let profiles_dir = dirs::app_profiles_dir().map_err(|err| -> String {
|
||||
format!("Failed to resolve profiles directory: {}", err).into()
|
||||
})?;
|
||||
let path = profiles_dir.join(&file);
|
||||
|
||||
let contents = fs::read_to_string(&path).map_err(|err| -> String {
|
||||
format!("Failed to read profile file {}: {}", path.display(), err).into()
|
||||
})?;
|
||||
|
||||
serde_yaml::from_str::<serde_yaml::Value>(&contents).map_err(|err| -> String {
|
||||
format!("Profile YAML parse failed for {}: {}", path.display(), err).into()
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user