Files
clash-verge-rev-lite/src-tauri/src/cmd/save_profile.rs
Tunglies a05ea64bcd perf: utilize smartstring for string handling (#5149)
* perf: utilize smartstring for string handling

- Updated various modules to replace standard String with smartstring::alias::String for improved performance and memory efficiency.
- Adjusted string manipulations and conversions throughout the codebase to ensure compatibility with the new smartstring type.
- Enhanced readability and maintainability by using `.into()` for conversions where applicable.
- Ensured that all instances of string handling in configuration, logging, and network management leverage the benefits of smartstring.

* fix: replace wrap_err with stringify_err for better error handling in UWP tool invocation

* refactor: update import path for StringifyErr and adjust string handling in sysopt

* fix: correct import path for CmdResult in UWP module

* fix: update argument type for execute_sysproxy_command to use std::string::String

* fix: add missing CmdResult import in UWP platform module

* fix: improve string handling and error messaging across multiple files

* style: format code for improved readability and consistency across multiple files

* fix: remove unused file
2025-10-22 16:25:44 +08:00

161 lines
6.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use super::CmdResult;
use crate::{
cmd::StringifyErr,
config::*,
core::{validate::CoreConfigValidator, *},
logging,
utils::{dirs, logging::Type},
};
use smartstring::alias::String;
use tokio::fs;
/// 保存profiles的配置
#[tauri::command]
pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdResult {
if file_data.is_none() {
return Ok(());
}
// 在异步操作前完成所有文件操作
let (file_path, original_content, is_merge_file) = {
let profiles = Config::profiles().await;
let profiles_guard = profiles.latest_ref();
let item = profiles_guard.get_item(&index).stringify_err()?;
// 确定是否为merge类型文件
let is_merge = item.itype.as_ref().is_some_and(|t| t == "merge");
let content = item.read_file().stringify_err()?;
let path = item.file.clone().ok_or("file field is null")?;
let profiles_dir = dirs::app_profiles_dir().stringify_err()?;
(profiles_dir.join(path.as_str()), content, is_merge)
};
// 保存新的配置文件
let file_data = file_data.ok_or("file_data is None")?;
fs::write(&file_path, &file_data).await.stringify_err()?;
let file_path_str = file_path.to_string_lossy().to_string();
logging!(
info,
Type::Config,
"[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}",
file_path_str,
is_merge_file
);
// 对于 merge 文件,只进行语法验证,不进行后续内核验证
if is_merge_file {
logging!(
info,
Type::Config,
"[cmd配置save] 检测到merge文件只进行语法验证"
);
match CoreConfigValidator::validate_config_file(&file_path_str, Some(true)).await {
Ok((true, _)) => {
logging!(info, Type::Config, "[cmd配置save] merge文件语法验证通过");
// 成功后尝试更新整体配置
match CoreManager::global().update_config().await {
Ok(_) => {
// 配置更新成功,刷新前端
handle::Handle::refresh_clash();
}
Err(e) => {
logging!(
warn,
Type::Config,
"[cmd配置save] 更新整体配置时发生错误: {}",
e
);
}
}
return Ok(());
}
Ok((false, error_msg)) => {
logging!(
warn,
Type::Config,
"[cmd配置save] merge文件语法验证失败: {}",
error_msg
);
// 恢复原始配置文件
fs::write(&file_path, original_content)
.await
.stringify_err()?;
// 发送合并文件专用错误通知
let result = (false, error_msg.clone());
crate::cmd::validate::handle_yaml_validation_notice(&result, "合并配置文件");
return Ok(());
}
Err(e) => {
logging!(error, Type::Config, "[cmd配置save] 验证过程发生错误: {}", e);
// 恢复原始配置文件
fs::write(&file_path, original_content)
.await
.stringify_err()?;
return Err(e.to_string().into());
}
}
}
// 非merge文件使用完整验证流程
match CoreConfigValidator::validate_config_file(&file_path_str, None).await {
Ok((true, _)) => {
logging!(info, Type::Config, "[cmd配置save] 验证成功");
Ok(())
}
Ok((false, error_msg)) => {
logging!(warn, Type::Config, "[cmd配置save] 验证失败: {}", error_msg);
// 恢复原始配置文件
fs::write(&file_path, original_content)
.await
.stringify_err()?;
// 智能判断错误类型
let is_script_error = file_path_str.ends_with(".js")
|| error_msg.contains("Script syntax error")
|| error_msg.contains("Script must contain a main function")
|| error_msg.contains("Failed to read script file");
if error_msg.contains("YAML syntax error")
|| error_msg.contains("Failed to read file:")
|| (!file_path_str.ends_with(".js") && !is_script_error)
{
// 普通YAML错误使用YAML通知处理
logging!(
info,
Type::Config,
"[cmd配置save] YAML配置文件验证失败发送通知"
);
let result = (false, error_msg.clone());
crate::cmd::validate::handle_yaml_validation_notice(&result, "YAML配置文件");
} else if is_script_error {
// 脚本错误使用专门的通知处理
logging!(
info,
Type::Config,
"[cmd配置save] 脚本文件验证失败,发送通知"
);
let result = (false, error_msg.clone());
crate::cmd::validate::handle_script_validation_notice(&result, "脚本文件");
} else {
// 普通配置错误使用一般通知
logging!(
info,
Type::Config,
"[cmd配置save] 其他类型验证失败,发送一般通知"
);
handle::Handle::notice_message("config_validate::error", error_msg.to_owned());
}
Ok(())
}
Err(e) => {
logging!(error, Type::Config, "[cmd配置save] 验证过程发生错误: {}", e);
// 恢复原始配置文件
fs::write(&file_path, original_content)
.await
.stringify_err()?;
Err(e.to_string().into())
}
}
}