mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 08:45:41 +08:00
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
This commit is contained in:
@@ -3,6 +3,7 @@ use anyhow::Error;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use reqwest_dav::list_cmd::{ListEntity, ListFile};
|
||||
use smartstring::alias::String;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env::{consts::OS, temp_dir},
|
||||
@@ -123,8 +124,11 @@ impl WebDavClient {
|
||||
}))
|
||||
.build()?,
|
||||
)
|
||||
.set_host(config.url)
|
||||
.set_auth(reqwest_dav::Auth::Basic(config.username, config.password))
|
||||
.set_host(config.url.into())
|
||||
.set_auth(reqwest_dav::Auth::Basic(
|
||||
config.username.into(),
|
||||
config.password.into(),
|
||||
))
|
||||
.build()?;
|
||||
|
||||
// 尝试检查目录是否存在,如果不存在尝试创建
|
||||
@@ -163,7 +167,7 @@ impl WebDavClient {
|
||||
|
||||
pub async fn upload(&self, file_path: PathBuf, file_name: String) -> Result<(), Error> {
|
||||
let client = self.get_client(Operation::Upload).await?;
|
||||
let webdav_path: String = format!("{}/{}", dirs::BACKUP_DIR, file_name);
|
||||
let webdav_path: String = format!("{}/{}", dirs::BACKUP_DIR, file_name).into();
|
||||
|
||||
// 读取文件并上传,如果失败尝试一次重试
|
||||
let file_content = fs::read(&file_path)?;
|
||||
@@ -248,8 +252,8 @@ impl WebDavClient {
|
||||
|
||||
pub fn create_backup() -> Result<(String, PathBuf), Error> {
|
||||
let now = chrono::Local::now().format("%Y-%m-%d_%H-%M-%S").to_string();
|
||||
let zip_file_name = format!("{OS}-backup-{now}.zip");
|
||||
let zip_path = temp_dir().join(&zip_file_name);
|
||||
let zip_file_name: String = format!("{OS}-backup-{now}.zip").into();
|
||||
let zip_path = temp_dir().join(zip_file_name.as_str());
|
||||
|
||||
let file = fs::File::create(&zip_path)?;
|
||||
let mut zip = zip::ZipWriter::new(file);
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::config::{Config, IVerge};
|
||||
use crate::core::{async_proxy_query::AsyncProxyQuery, handle};
|
||||
use crate::process::AsyncHandler;
|
||||
use once_cell::sync::Lazy;
|
||||
use smartstring::alias::String;
|
||||
use sysproxy::{Autoproxy, Sysproxy};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -426,13 +427,15 @@ impl EventDrivenProxyManager {
|
||||
};
|
||||
|
||||
let port = verge_mixed_port.unwrap_or(default_port);
|
||||
let host = proxy_host.unwrap_or_else(|| network::DEFAULT_PROXY_HOST.into());
|
||||
let host = proxy_host
|
||||
.unwrap_or_else(|| network::DEFAULT_PROXY_HOST.into())
|
||||
.into();
|
||||
|
||||
Sysproxy {
|
||||
enable: true,
|
||||
host,
|
||||
port,
|
||||
bypass: Self::get_bypass_config().await,
|
||||
bypass: Self::get_bypass_config().await.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,9 +448,9 @@ impl EventDrivenProxyManager {
|
||||
let custom = verge.system_proxy_bypass.as_deref().unwrap_or("");
|
||||
|
||||
match (use_default, custom.is_empty()) {
|
||||
(_, true) => bypass::DEFAULT.to_string(),
|
||||
(true, false) => format!("{},{}", bypass::DEFAULT, custom),
|
||||
(false, false) => custom.to_string(),
|
||||
(_, true) => bypass::DEFAULT.into(),
|
||||
(true, false) => format!("{},{}", bypass::DEFAULT, custom).into(),
|
||||
(false, false) => custom.into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::{APP_HANDLE, constants::timing, singleton};
|
||||
use parking_lot::RwLock;
|
||||
use smartstring::alias::String;
|
||||
use std::{sync::Arc, thread};
|
||||
use tauri::{AppHandle, Manager, WebviewWindow};
|
||||
use tauri_plugin_mihomo::{Mihomo, MihomoExt};
|
||||
@@ -199,7 +200,7 @@ impl Handle {
|
||||
pub fn set_activation_policy(&self, policy: tauri::ActivationPolicy) -> Result<(), String> {
|
||||
Self::app_handle()
|
||||
.set_activation_policy(policy)
|
||||
.map_err(|e| e.to_string())
|
||||
.map_err(|e| e.to_string().into())
|
||||
}
|
||||
|
||||
pub fn set_activation_policy_regular(&self) {
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::{
|
||||
};
|
||||
use anyhow::{Result, bail};
|
||||
use parking_lot::Mutex;
|
||||
use smartstring::alias::String;
|
||||
use std::{collections::HashMap, fmt, str::FromStr, sync::Arc};
|
||||
use tauri::{AppHandle, Manager};
|
||||
use tauri_plugin_global_shortcut::{Code, GlobalShortcutExt, ShortcutState};
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{
|
||||
utils::{dirs, help, logging::Type},
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use smartstring::alias::String;
|
||||
use std::{path::PathBuf, time::Instant};
|
||||
use tauri_plugin_mihomo::Error as MihomoError;
|
||||
use tokio::time::sleep;
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::{
|
||||
utils::logging::Type,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use smartstring::alias::String;
|
||||
|
||||
impl CoreManager {
|
||||
pub async fn start_core(&self) -> Result<()> {
|
||||
@@ -48,7 +49,7 @@ impl CoreManager {
|
||||
.ok_or_else(|| "Clash core cannot be None".to_string())?;
|
||||
|
||||
if !IVerge::VALID_CLASH_CORES.contains(&core.as_str()) {
|
||||
return Err(format!("Invalid clash core: {}", core));
|
||||
return Err(format!("Invalid clash core: {}", core).into());
|
||||
}
|
||||
|
||||
Config::verge().await.draft_mut().clash_core = clash_core;
|
||||
@@ -61,7 +62,9 @@ impl CoreManager {
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
self.apply_config(run_path).await.map_err(|e| e.to_string())
|
||||
self.apply_config(run_path)
|
||||
.await
|
||||
.map_err(|e| e.to_string().into())
|
||||
}
|
||||
|
||||
async fn prepare_startup(&self) -> Result<()> {
|
||||
|
||||
@@ -37,7 +37,7 @@ impl CoreManager {
|
||||
|
||||
let (mut rx, child) = app_handle
|
||||
.shell()
|
||||
.sidecar(&clash_core)?
|
||||
.sidecar(clash_core.as_str())?
|
||||
.args([
|
||||
"-d",
|
||||
dirs::path_to_str(&config_dir)?,
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::{
|
||||
utils::logging::Type,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use smartstring::alias::String;
|
||||
use std::{
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{
|
||||
utils::logging::Type,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use smartstring::alias::String;
|
||||
use std::sync::Arc;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use sysproxy::{Autoproxy, Sysproxy};
|
||||
@@ -45,7 +46,7 @@ async fn get_bypass() -> String {
|
||||
if custom_bypass.is_empty() {
|
||||
DEFAULT_BYPASS.into()
|
||||
} else if use_default {
|
||||
format!("{DEFAULT_BYPASS},{custom_bypass}")
|
||||
format!("{DEFAULT_BYPASS},{custom_bypass}").into()
|
||||
} else {
|
||||
custom_bypass
|
||||
}
|
||||
@@ -53,7 +54,7 @@ async fn get_bypass() -> String {
|
||||
|
||||
// Uses tokio Command with CREATE_NO_WINDOW flag to avoid DLL initialization issues during shutdown
|
||||
#[cfg(target_os = "windows")]
|
||||
async fn execute_sysproxy_command(args: Vec<String>) -> Result<()> {
|
||||
async fn execute_sysproxy_command(args: Vec<std::string::String>) -> Result<()> {
|
||||
use crate::utils::dirs;
|
||||
use anyhow::bail;
|
||||
#[allow(unused_imports)] // Required for .creation_flags() method
|
||||
@@ -68,7 +69,7 @@ async fn execute_sysproxy_command(args: Vec<String>) -> Result<()> {
|
||||
}
|
||||
|
||||
let output = Command::new(sysproxy_exe)
|
||||
.args(&args)
|
||||
.args(args)
|
||||
.creation_flags(0x08000000) // CREATE_NO_WINDOW - 隐藏窗口
|
||||
.output()
|
||||
.await?;
|
||||
@@ -132,9 +133,9 @@ impl Sysopt {
|
||||
{
|
||||
let mut sys = Sysproxy {
|
||||
enable: false,
|
||||
host: proxy_host.clone(),
|
||||
host: proxy_host.clone().into(),
|
||||
port,
|
||||
bypass: get_bypass().await,
|
||||
bypass: get_bypass().await.into(),
|
||||
};
|
||||
let mut auto = Autoproxy {
|
||||
enable: false,
|
||||
@@ -178,13 +179,13 @@ impl Sysopt {
|
||||
return result;
|
||||
}
|
||||
|
||||
let args = if pac_enable {
|
||||
let args: Vec<std::string::String> = if pac_enable {
|
||||
let address = format!("http://{proxy_host}:{pac_port}/commands/pac");
|
||||
vec!["pac".into(), address]
|
||||
} else {
|
||||
let address = format!("{proxy_host}:{port}");
|
||||
let bypass = get_bypass().await;
|
||||
vec!["global".into(), address, bypass]
|
||||
vec!["global".into(), address, bypass.into()]
|
||||
};
|
||||
|
||||
execute_sysproxy_command(args).await?;
|
||||
|
||||
@@ -2,6 +2,7 @@ use crate::{config::Config, feat, logging, logging_error, singleton, utils::logg
|
||||
use anyhow::{Context, Result};
|
||||
use delay_timer::prelude::{DelayTimer, DelayTimerBuilder, TaskBuilder};
|
||||
use parking_lot::RwLock;
|
||||
use smartstring::alias::String;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
pin::Pin,
|
||||
|
||||
@@ -19,6 +19,7 @@ use super::handle;
|
||||
use anyhow::Result;
|
||||
use futures::future::join_all;
|
||||
use parking_lot::Mutex;
|
||||
use smartstring::alias::String;
|
||||
use std::collections::HashMap;
|
||||
use std::{
|
||||
fs,
|
||||
@@ -218,7 +219,7 @@ impl Tray {
|
||||
|
||||
let app_handle = handle::Handle::app_handle();
|
||||
let tray_event = { Config::verge().await.latest_ref().tray_event.clone() };
|
||||
let tray_event: String = tray_event.unwrap_or("main_window".into());
|
||||
let tray_event = tray_event.unwrap_or("main_window".into());
|
||||
let tray = app_handle
|
||||
.tray_by_id("main")
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get main tray"))?;
|
||||
@@ -625,7 +626,7 @@ async fn create_tray_menu(
|
||||
.iter()
|
||||
.filter_map(|group| group.get("name"))
|
||||
.filter_map(|name| name.as_str())
|
||||
.map(|name| name.to_string())
|
||||
.map(|name| name.into())
|
||||
.collect::<Vec<String>>()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
@@ -671,7 +672,7 @@ async fn create_tray_menu(
|
||||
let is_current_profile = Config::profiles()
|
||||
.await
|
||||
.data_mut()
|
||||
.is_current_profile_index(profile_uid.to_string());
|
||||
.is_current_profile_index(profile_uid.clone());
|
||||
CheckMenuItem::with_id(
|
||||
&app_handle,
|
||||
format!("profiles_{profile_uid}"),
|
||||
@@ -780,7 +781,7 @@ async fn create_tray_menu(
|
||||
&group_items_refs,
|
||||
) {
|
||||
let insertion_index = submenus.len();
|
||||
submenus.push((group_name.to_string(), insertion_index, submenu));
|
||||
submenus.push((group_name.into(), insertion_index, submenu));
|
||||
} else {
|
||||
log::warn!(target: "app", "创建代理组子菜单失败: {}", group_name);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use smartstring::alias::String;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
@@ -124,7 +125,7 @@ impl CoreConfigValidator {
|
||||
let content = match std::fs::read_to_string(config_path) {
|
||||
Ok(content) => content,
|
||||
Err(err) => {
|
||||
let error_msg = format!("Failed to read file: {err}");
|
||||
let error_msg = format!("Failed to read file: {err}").into();
|
||||
logging!(error, Type::Validate, "无法读取文件: {}", error_msg);
|
||||
return Ok((false, error_msg));
|
||||
}
|
||||
@@ -138,7 +139,7 @@ impl CoreConfigValidator {
|
||||
}
|
||||
Err(err) => {
|
||||
// 使用标准化的前缀,以便错误处理函数能正确识别
|
||||
let error_msg = format!("YAML syntax error: {err}");
|
||||
let error_msg = format!("YAML syntax error: {err}").into();
|
||||
logging!(error, Type::Validate, "YAML语法错误: {}", error_msg);
|
||||
Ok((false, error_msg))
|
||||
}
|
||||
@@ -151,7 +152,7 @@ impl CoreConfigValidator {
|
||||
let content = match std::fs::read_to_string(path) {
|
||||
Ok(content) => content,
|
||||
Err(err) => {
|
||||
let error_msg = format!("Failed to read script file: {err}");
|
||||
let error_msg = format!("Failed to read script file: {err}").into();
|
||||
logging!(warn, Type::Validate, "脚本语法错误: {}", err);
|
||||
//handle::Handle::notice_message("config_validate::script_syntax_error", &error_msg);
|
||||
return Ok((false, error_msg));
|
||||
@@ -184,7 +185,7 @@ impl CoreConfigValidator {
|
||||
Ok((true, String::new()))
|
||||
}
|
||||
Err(err) => {
|
||||
let error_msg = format!("Script syntax error: {err}");
|
||||
let error_msg = format!("Script syntax error: {err}").into();
|
||||
logging!(warn, Type::Validate, "脚本语法错误: {}", err);
|
||||
//handle::Handle::notice_message("config_validate::script_syntax_error", &error_msg);
|
||||
Ok((false, error_msg))
|
||||
@@ -205,7 +206,7 @@ impl CoreConfigValidator {
|
||||
|
||||
// 检查文件是否存在
|
||||
if !std::path::Path::new(config_path).exists() {
|
||||
let error_msg = format!("File not found: {config_path}");
|
||||
let error_msg = format!("File not found: {config_path}").into();
|
||||
//handle::Handle::notice_message("config_validate::file_not_found", &error_msg);
|
||||
return Ok((false, error_msg));
|
||||
}
|
||||
@@ -282,13 +283,13 @@ impl CoreConfigValidator {
|
||||
// 使用子进程运行clash验证配置
|
||||
let output = app_handle
|
||||
.shell()
|
||||
.sidecar(clash_core)?
|
||||
.sidecar(clash_core.as_str())?
|
||||
.args(["-t", "-d", app_dir_str, "-f", config_path])
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let stderr = std::string::String::from_utf8_lossy(&output.stderr);
|
||||
let stdout = std::string::String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
// 检查进程退出状态和错误输出
|
||||
let error_keywords = ["FATA", "fatal", "Parse config error", "level=fatal"];
|
||||
@@ -314,7 +315,7 @@ impl CoreConfigValidator {
|
||||
};
|
||||
|
||||
logging!(info, Type::Validate, "-------- 验证结束 --------");
|
||||
Ok((false, error_msg)) // 返回错误消息给调用者处理
|
||||
Ok((false, error_msg.into())) // 返回错误消息给调用者处理
|
||||
} else {
|
||||
logging!(info, Type::Validate, "验证成功");
|
||||
logging!(info, Type::Validate, "-------- 验证结束 --------");
|
||||
|
||||
Reference in New Issue
Block a user