refactor(cmd): move switch-validation helper into new profile_switch module

This commit is contained in:
Slinetrac
2025-10-26 17:39:30 +08:00
Unverified
parent fb7250cc6b
commit 59f4dbe16d
3 changed files with 79 additions and 69 deletions

View File

@@ -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;

View File

@@ -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;

View 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(())
}