Refactor string handling to use into() instead of to_string() for improved performance and consistency across the codebase. This change affects various modules including app.rs, clash.rs, config.rs, core.rs, service.rs, and others, ensuring that string conversions are streamlined and more idiomatic.

This commit is contained in:
Tunglies
2025-10-14 09:24:39 +08:00
parent 44eb781060
commit 924e7d1022
22 changed files with 167 additions and 161 deletions

View File

@@ -68,9 +68,7 @@ pub fn get_portable_flag() -> CmdResult<bool> {
/// 获取应用目录 /// 获取应用目录
#[tauri::command] #[tauri::command]
pub fn get_app_dir() -> CmdResult<String> { pub fn get_app_dir() -> CmdResult<String> {
let app_home_dir = wrap_err!(dirs::app_home_dir())? let app_home_dir = wrap_err!(dirs::app_home_dir())?.to_string_lossy().into();
.to_string_lossy()
.to_string();
Ok(app_home_dir) Ok(app_home_dir)
} }
@@ -88,7 +86,7 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
let icon_path = icon_cache_dir.join(&name); let icon_path = icon_cache_dir.join(&name);
if icon_path.exists() { if icon_path.exists() {
return Ok(icon_path.to_string_lossy().to_string()); return Ok(icon_path.to_string_lossy().into());
} }
if !icon_cache_dir.exists() { if !icon_cache_dir.exists() {
@@ -120,7 +118,7 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
Ok(file) => file, Ok(file) => file,
Err(_) => { Err(_) => {
if icon_path.exists() { if icon_path.exists() {
return Ok(icon_path.to_string_lossy().to_string()); return Ok(icon_path.to_string_lossy().into());
} }
return Err("Failed to create temporary file".into()); return Err("Failed to create temporary file".into());
} }
@@ -135,7 +133,7 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
Err(_) => { Err(_) => {
let _ = std::fs::remove_file(&temp_path); let _ = std::fs::remove_file(&temp_path);
if icon_path.exists() { if icon_path.exists() {
return Ok(icon_path.to_string_lossy().to_string()); return Ok(icon_path.to_string_lossy().into());
} }
} }
} }
@@ -143,7 +141,7 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
let _ = std::fs::remove_file(&temp_path); let _ = std::fs::remove_file(&temp_path);
} }
Ok(icon_path.to_string_lossy().to_string()) Ok(icon_path.to_string_lossy().into())
} else { } else {
let _ = std::fs::remove_file(&temp_path); let _ = std::fs::remove_file(&temp_path);
Err(format!("下载的内容不是有效图片: {url}")) Err(format!("下载的内容不是有效图片: {url}"))
@@ -168,9 +166,9 @@ pub fn copy_icon_file(path: String, icon_info: IconInfo) -> CmdResult<String> {
if !icon_dir.exists() { if !icon_dir.exists() {
let _ = fs::create_dir_all(&icon_dir); let _ = fs::create_dir_all(&icon_dir);
} }
let ext = match file_path.extension() { let ext: String = match file_path.extension() {
Some(e) => e.to_string_lossy().to_string(), Some(e) => e.to_string_lossy().into(),
None => "ico".to_string(), None => "ico".into(),
}; };
let dest_path = icon_dir.join(format!( let dest_path = icon_dir.join(format!(
@@ -196,11 +194,11 @@ pub fn copy_icon_file(path: String, icon_info: IconInfo) -> CmdResult<String> {
dest_path dest_path
); );
match fs::copy(file_path, &dest_path) { match fs::copy(file_path, &dest_path) {
Ok(_) => Ok(dest_path.to_string_lossy().to_string()), Ok(_) => Ok(dest_path.to_string_lossy().into()),
Err(err) => Err(err.to_string()), Err(err) => Err(err.to_string()),
} }
} else { } else {
Err("file not found".to_string()) Err("file not found".into())
} }
} }

View File

@@ -2,6 +2,7 @@ use std::collections::VecDeque;
use super::CmdResult; use super::CmdResult;
use crate::{ use crate::{
cmd::StringifyErr,
config::Config, config::Config,
core::{CoreManager, handle}, core::{CoreManager, handle},
}; };
@@ -66,7 +67,7 @@ pub async fn change_clash_core(clash_core: String) -> CmdResult<Option<String>>
} }
} }
Err(err) => { Err(err) => {
let error_msg = err.to_string(); let error_msg = err.into();
logging!(error, Type::Core, "failed to change core: {error_msg}"); logging!(error, Type::Core, "failed to change core: {error_msg}");
handle::Handle::notice_message("config_core::change_error", &error_msg); handle::Handle::notice_message("config_core::change_error", &error_msg);
Ok(Some(error_msg)) Ok(Some(error_msg))
@@ -126,14 +127,12 @@ pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
// 获取DNS配置文件路径 // 获取DNS配置文件路径
let dns_path = dirs::app_home_dir() let dns_path = dirs::app_home_dir()
.map_err(|e| e.to_string())? .stringify_err()?
.join("dns_config.yaml"); .join("dns_config.yaml");
// 保存DNS配置到文件 // 保存DNS配置到文件
let yaml_str = serde_yaml_ng::to_string(&dns_config).map_err(|e| e.to_string())?; let yaml_str = serde_yaml_ng::to_string(&dns_config).stringify_err()?;
fs::write(&dns_path, yaml_str) fs::write(&dns_path, yaml_str).await.stringify_err()?;
.await
.map_err(|e| e.to_string())?;
logging!(info, Type::Config, "DNS config saved to {dns_path:?}"); logging!(info, Type::Config, "DNS config saved to {dns_path:?}");
Ok(()) Ok(())
@@ -151,7 +150,7 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
if apply { if apply {
// 读取DNS配置文件 // 读取DNS配置文件
let dns_path = dirs::app_home_dir() let dns_path = dirs::app_home_dir()
.map_err(|e| e.to_string())? .stringify_err()?
.join("dns_config.yaml"); .join("dns_config.yaml");
if !dns_path.exists() { if !dns_path.exists() {
@@ -159,16 +158,16 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
return Err("DNS config file not found".into()); return Err("DNS config file not found".into());
} }
let dns_yaml = tokio::fs::read_to_string(&dns_path).await.map_err(|e| { let dns_yaml = tokio::fs::read_to_string(&dns_path)
logging!(error, Type::Config, "Failed to read DNS config: {e}"); .await
e.to_string() .stringify_err_log(|e| {
})?; logging!(error, Type::Config, "Failed to read DNS config: {e}");
})?;
// 解析DNS配置 // 解析DNS配置
let patch_config = let patch_config = serde_yaml_ng::from_str::<serde_yaml_ng::Mapping>(&dns_yaml)
serde_yaml_ng::from_str::<serde_yaml_ng::Mapping>(&dns_yaml).map_err(|e| { .stringify_err_log(|e| {
logging!(error, Type::Config, "Failed to parse DNS config: {e}"); logging!(error, Type::Config, "Failed to parse DNS config: {e}");
e.to_string()
})?; })?;
logging!(info, Type::Config, "Applying DNS config from file"); logging!(info, Type::Config, "Applying DNS config from file");
@@ -181,24 +180,19 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
Config::runtime().await.draft_mut().patch_config(patch); Config::runtime().await.draft_mut().patch_config(patch);
// 重新生成配置 // 重新生成配置
Config::generate().await.map_err(|err| { Config::generate().await.stringify_err_log(|err| {
logging!( let err = format!("Failed to regenerate config with DNS: {err}");
error, logging!(error, Type::Config, "{err}");
Type::Config,
"Failed to regenerate config with DNS: {err}"
);
"Failed to regenerate config with DNS".to_string()
})?; })?;
// 应用新配置 // 应用新配置
CoreManager::global().update_config().await.map_err(|err| { CoreManager::global()
logging!( .update_config()
error, .await
Type::Config, .stringify_err_log(|err| {
"Failed to apply config with DNS: {err}" let err = format!("Failed to apply config with DNS: {err}");
); logging!(error, Type::Config, "{err}");
"Failed to apply config with DNS".to_string() })?;
})?;
logging!(info, Type::Config, "DNS config successfully applied"); logging!(info, Type::Config, "DNS config successfully applied");
handle::Handle::refresh_clash(); handle::Handle::refresh_clash();
@@ -210,19 +204,18 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
"DNS settings disabled, regenerating config" "DNS settings disabled, regenerating config"
); );
Config::generate().await.map_err(|err| { Config::generate().await.stringify_err_log(|err| {
logging!(error, Type::Config, "Failed to regenerate config: {err}"); let err = format!("Failed to regenerate config: {err}");
"Failed to regenerate config".to_string() logging!(error, Type::Config, "{err}");
})?; })?;
CoreManager::global().update_config().await.map_err(|err| { CoreManager::global()
logging!( .update_config()
error, .await
Type::Config, .stringify_err_log(|err| {
"Failed to apply regenerated config: {err}" let err = format!("Failed to apply regenerated config: {err}");
); logging!(error, Type::Config, "{err}");
"Failed to apply regenerated config".to_string() })?;
})?;
logging!(info, Type::Config, "Config regenerated successfully"); logging!(info, Type::Config, "Config regenerated successfully");
handle::Handle::refresh_clash(); handle::Handle::refresh_clash();
@@ -237,7 +230,7 @@ pub fn check_dns_config_exists() -> CmdResult<bool> {
use crate::utils::dirs; use crate::utils::dirs;
let dns_path = dirs::app_home_dir() let dns_path = dirs::app_home_dir()
.map_err(|e| e.to_string())? .stringify_err()?
.join("dns_config.yaml"); .join("dns_config.yaml");
Ok(dns_path.exists()) Ok(dns_path.exists())
@@ -250,16 +243,14 @@ pub async fn get_dns_config_content() -> CmdResult<String> {
use tokio::fs; use tokio::fs;
let dns_path = dirs::app_home_dir() let dns_path = dirs::app_home_dir()
.map_err(|e| e.to_string())? .stringify_err()?
.join("dns_config.yaml"); .join("dns_config.yaml");
if !fs::try_exists(&dns_path).await.map_err(|e| e.to_string())? { if !fs::try_exists(&dns_path).await.stringify_err()? {
return Err("DNS config file not found".into()); return Err("DNS config file not found".into());
} }
let content = fs::read_to_string(&dns_path) let content = fs::read_to_string(&dns_path).await.stringify_err()?;
.await
.map_err(|e| e.to_string())?;
Ok(content) Ok(content)
} }
@@ -268,21 +259,18 @@ pub async fn get_dns_config_content() -> CmdResult<String> {
pub async fn validate_dns_config() -> CmdResult<(bool, String)> { pub async fn validate_dns_config() -> CmdResult<(bool, String)> {
use crate::{core::CoreManager, utils::dirs}; use crate::{core::CoreManager, utils::dirs};
let app_dir = dirs::app_home_dir().map_err(|e| e.to_string())?; let app_dir = dirs::app_home_dir().stringify_err()?;
let dns_path = app_dir.join("dns_config.yaml"); let dns_path = app_dir.join("dns_config.yaml");
let dns_path_str = dns_path.to_str().unwrap_or_default(); let dns_path_str = dns_path.to_str().unwrap_or_default();
if !dns_path.exists() { if !dns_path.exists() {
return Ok((false, "DNS config file not found".to_string())); return Ok((false, "DNS config file not found".into()));
} }
match CoreManager::global() Ok(CoreManager::global()
.validate_config_file(dns_path_str, None) .validate_config_file(dns_path_str, None)
.await .await
{ .stringify_err()?)
Ok(result) => Ok(result),
Err(e) => Err(e.to_string()),
}
} }
#[tauri::command] #[tauri::command]

View File

@@ -35,3 +35,27 @@ pub use uwp::*;
pub use validate::*; pub use validate::*;
pub use verge::*; pub use verge::*;
pub use webdav::*; pub use webdav::*;
pub trait StringifyErr<T> {
fn stringify_err(self) -> CmdResult<T>;
fn stringify_err_log<F>(self, log_fn: F) -> CmdResult<T>
where
F: Fn(&str);
}
impl<T, E: std::fmt::Display> StringifyErr<T> for Result<T, E> {
fn stringify_err(self) -> CmdResult<T> {
self.map_err(|e| e.to_string())
}
fn stringify_err_log<F>(self, log_fn: F) -> CmdResult<T>
where
F: Fn(&str),
{
self.map_err(|e| {
let msg = e.to_string();
log_fn(&msg);
msg
})
}
}

View File

@@ -35,7 +35,7 @@ impl IClashTemp {
if let Some(Value::String(s)) = map.get_mut("secret") if let Some(Value::String(s)) = map.get_mut("secret")
&& s.is_empty() && s.is_empty()
{ {
*s = "set-your-secret".to_string(); *s = "set-your-secret".into();
} }
Self(Self::guard(map)) Self(Self::guard(map))
} }
@@ -323,10 +323,10 @@ impl IClashTemp {
// 总是使用当前的 IPC 路径,确保配置文件与运行时路径一致 // 总是使用当前的 IPC 路径,确保配置文件与运行时路径一致
ipc_path() ipc_path()
.ok() .ok()
.and_then(|path| path_to_str(&path).ok().map(|s| s.to_string())) .and_then(|path| path_to_str(&path).ok().map(|s| s.into()))
.unwrap_or_else(|| { .unwrap_or_else(|| {
log::error!(target: "app", "Failed to get IPC path, using default"); log::error!(target: "app", "Failed to get IPC path, using default");
"127.0.0.1:9090".to_string() "127.0.0.1:9090".into()
}) })
} }
} }

View File

@@ -58,19 +58,19 @@ impl Config {
if Self::profiles() if Self::profiles()
.await .await
.latest_ref() .latest_ref()
.get_item(&"Merge".to_string()) .get_item(&"Merge".into())
.is_err() .is_err()
{ {
let merge_item = PrfItem::from_merge(Some("Merge".to_string()))?; let merge_item = PrfItem::from_merge(Some("Merge".into()))?;
profiles_append_item_safe(merge_item.clone()).await?; profiles_append_item_safe(merge_item.clone()).await?;
} }
if Self::profiles() if Self::profiles()
.await .await
.latest_ref() .latest_ref()
.get_item(&"Script".to_string()) .get_item(&"Script".into())
.is_err() .is_err()
{ {
let script_item = PrfItem::from_script(Some("Script".to_string()))?; let script_item = PrfItem::from_script(Some("Script".into()))?;
profiles_append_item_safe(script_item.clone()).await?; profiles_append_item_safe(script_item.clone()).await?;
} }
// 生成运行时配置 // 生成运行时配置
@@ -238,8 +238,8 @@ mod tests {
#[allow(unused_variables)] #[allow(unused_variables)]
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
fn test_prfitem_from_merge_size() { fn test_prfitem_from_merge_size() {
let merge_item = PrfItem::from_merge(Some("Merge".to_string())) let merge_item =
.expect("Failed to create merge item in test"); PrfItem::from_merge(Some("Merge".into())).expect("Failed to create merge item in test");
let prfitem_size = mem::size_of_val(&merge_item); let prfitem_size = mem::size_of_val(&merge_item);
// Boxed version // Boxed version
let boxed_merge_item = Box::new(merge_item); let boxed_merge_item = Box::new(merge_item);

View File

@@ -312,12 +312,12 @@ impl PrfItem {
Some(filename) => { Some(filename) => {
let iter = percent_encoding::percent_decode(filename.as_bytes()); let iter = percent_encoding::percent_decode(filename.as_bytes());
let filename = iter.decode_utf8().unwrap_or_default(); let filename = iter.decode_utf8().unwrap_or_default();
filename.split("''").last().map(|s| s.to_string()) filename.split("''").last().map(|s| s.into())
} }
None => match help::parse_str::<String>(filename, "filename") { None => match help::parse_str::<String>(filename, "filename") {
Some(filename) => { Some(filename) => {
let filename = filename.trim_matches('"'); let filename = filename.trim_matches('"');
Some(filename.to_string()) Some(filename.into())
} }
None => None, None => None,
}, },
@@ -341,7 +341,7 @@ impl PrfItem {
let home = match header.get("profile-web-page-url") { let home = match header.get("profile-web-page-url") {
Some(value) => { Some(value) => {
let str_value = value.to_str().unwrap_or(""); let str_value = value.to_str().unwrap_or("");
Some(str_value.to_string()) Some(str_value.into())
} }
None => None, None => None,
}; };

View File

@@ -151,7 +151,7 @@ impl IProfiles {
} }
if self.current.is_none() if self.current.is_none()
&& (item.itype == Some("remote".to_string()) || item.itype == Some("local".to_string())) && (item.itype == Some("remote".into()) || item.itype == Some("local".into()))
{ {
self.current = uid; self.current = uid;
} }
@@ -434,9 +434,7 @@ impl IProfiles {
if current == uid { if current == uid {
self.current = None; self.current = None;
for item in items.iter() { for item in items.iter() {
if item.itype == Some("remote".to_string()) if item.itype == Some("remote".into()) || item.itype == Some("local".into()) {
|| item.itype == Some("local".to_string())
{
self.current = item.uid.clone(); self.current = item.uid.clone();
break; break;
} }
@@ -602,7 +600,7 @@ impl IProfiles {
if !active_files.contains(file_name) { if !active_files.contains(file_name) {
match std::fs::remove_file(&path) { match std::fs::remove_file(&path) {
Ok(_) => { Ok(_) => {
deleted_files.push(file_name.to_string()); deleted_files.push(file_name.into());
log::info!(target: "app", "已清理冗余文件: {file_name}"); log::info!(target: "app", "已清理冗余文件: {file_name}");
} }
Err(e) => { Err(e) => {
@@ -635,8 +633,8 @@ impl IProfiles {
fn get_protected_global_files(&self) -> HashSet<String> { fn get_protected_global_files(&self) -> HashSet<String> {
let mut protected_files = HashSet::new(); let mut protected_files = HashSet::new();
protected_files.insert("Merge.yaml".to_string()); protected_files.insert("Merge.yaml".into());
protected_files.insert("Script.js".to_string()); protected_files.insert("Script.js".into());
protected_files protected_files
} }

View File

@@ -258,7 +258,7 @@ impl IVerge {
"启动时发现无效的clash_core配置: '{}', 将自动修正为 'verge-mihomo'", "启动时发现无效的clash_core配置: '{}', 将自动修正为 'verge-mihomo'",
core core
); );
config.clash_core = Some("verge-mihomo".to_string()); config.clash_core = Some("verge-mihomo".into());
needs_fix = true; needs_fix = true;
} }
} else { } else {
@@ -267,7 +267,7 @@ impl IVerge {
Type::Config, Type::Config,
"启动时发现未配置clash_core, 将设置为默认值 'verge-mihomo'" "启动时发现未配置clash_core, 将设置为默认值 'verge-mihomo'"
); );
config.clash_core = Some("verge-mihomo".to_string()); config.clash_core = Some("verge-mihomo".into());
needs_fix = true; needs_fix = true;
} }
@@ -311,7 +311,7 @@ impl IVerge {
pub fn get_valid_clash_core(&self) -> String { pub fn get_valid_clash_core(&self) -> String {
self.clash_core self.clash_core
.clone() .clone()
.unwrap_or_else(|| "verge-mihomo".to_string()) .unwrap_or_else(|| "verge-mihomo".into())
} }
fn get_system_language() -> String { fn get_system_language() -> String {
@@ -322,8 +322,8 @@ impl IVerge {
let lang_code = sys_lang.split(['_', '-']).next().unwrap_or("en"); let lang_code = sys_lang.split(['_', '-']).next().unwrap_or("en");
let supported_languages = i18n::get_supported_languages(); let supported_languages = i18n::get_supported_languages();
if supported_languages.contains(&lang_code.to_string()) { if supported_languages.contains(&lang_code.into()) {
lang_code.to_string() lang_code.into()
} else { } else {
String::from("en") String::from("en")
} }

View File

@@ -27,7 +27,7 @@ impl Default for AsyncSysproxy {
fn default() -> Self { fn default() -> Self {
Self { Self {
enable: false, enable: false,
host: "127.0.0.1".to_string(), host: "127.0.0.1".into(),
port: 7897, port: 7897,
bypass: String::new(), bypass: String::new(),
} }
@@ -153,7 +153,7 @@ impl AsyncProxyQuery {
log::debug!(target: "app", "PAC配置启用: URL={pac_url}, AutoDetect={auto_detect}"); log::debug!(target: "app", "PAC配置启用: URL={pac_url}, AutoDetect={auto_detect}");
if pac_url.is_empty() && auto_detect != 0 { if pac_url.is_empty() && auto_detect != 0 {
pac_url = "auto-detect".to_string(); pac_url = "auto-detect".into();
} }
Ok(AsyncAutoproxy { Ok(AsyncAutoproxy {
@@ -191,7 +191,7 @@ impl AsyncProxyQuery {
// 正确解析包含冒号的URL // 正确解析包含冒号的URL
// 格式: "ProxyAutoConfigURLString : http://127.0.0.1:11233/commands/pac" // 格式: "ProxyAutoConfigURLString : http://127.0.0.1:11233/commands/pac"
if let Some(colon_pos) = line.find(" : ") { if let Some(colon_pos) = line.find(" : ") {
pac_url = line[colon_pos + 3..].trim().to_string(); pac_url = line[colon_pos + 3..].trim().into();
} }
} }
} }
@@ -227,7 +227,7 @@ impl AsyncProxyQuery {
if let Ok(output) = output if let Ok(output) = output
&& output.status.success() && output.status.success()
{ {
let mode = String::from_utf8_lossy(&output.stdout).trim().to_string(); let mode = String::from_utf8_lossy(&output.stdout).trim().into();
if mode.contains("auto") { if mode.contains("auto") {
// 获取 PAC URL // 获取 PAC URL
let pac_output = Command::new("gsettings") let pac_output = Command::new("gsettings")
@@ -242,7 +242,7 @@ impl AsyncProxyQuery {
.trim() .trim()
.trim_matches('\'') .trim_matches('\'')
.trim_matches('"') .trim_matches('"')
.to_string(); .into();
if !pac_url.is_empty() { if !pac_url.is_empty() {
return Ok(AsyncAutoproxy { return Ok(AsyncAutoproxy {
@@ -356,7 +356,7 @@ impl AsyncProxyQuery {
if !proxy_server.is_empty() { if !proxy_server.is_empty() {
// 解析服务器地址和端口 // 解析服务器地址和端口
let (host, port) = if let Some(colon_pos) = proxy_server.rfind(':') { let (host, port) = if let Some(colon_pos) = proxy_server.rfind(':') {
let host = proxy_server[..colon_pos].to_string(); let host = proxy_server[..colon_pos].into();
let port = proxy_server[colon_pos + 1..].parse::<u16>().unwrap_or(8080); let port = proxy_server[colon_pos + 1..].parse::<u16>().unwrap_or(8080);
(host, port) (host, port)
} else { } else {
@@ -391,7 +391,7 @@ impl AsyncProxyQuery {
let mut http_enabled = false; let mut http_enabled = false;
let mut http_host = String::new(); let mut http_host = String::new();
let mut http_port = 8080u16; let mut http_port = 8080u16;
let mut exceptions = Vec::new(); let mut exceptions: Vec<String> = Vec::new();
for line in stdout.lines() { for line in stdout.lines() {
let line = line.trim(); let line = line.trim();
@@ -399,7 +399,7 @@ impl AsyncProxyQuery {
http_enabled = true; http_enabled = true;
} else if line.contains("HTTPProxy") && !line.contains("Port") { } else if line.contains("HTTPProxy") && !line.contains("Port") {
if let Some(host_part) = line.split(':').nth(1) { if let Some(host_part) = line.split(':').nth(1) {
http_host = host_part.trim().to_string(); http_host = host_part.trim().into();
} }
} else if line.contains("HTTPPort") { } else if line.contains("HTTPPort") {
if let Some(port_part) = line.split(':').nth(1) if let Some(port_part) = line.split(':').nth(1)
@@ -412,7 +412,7 @@ impl AsyncProxyQuery {
if let Some(list_part) = line.split(':').nth(1) { if let Some(list_part) = line.split(':').nth(1) {
let list = list_part.trim(); let list = list_part.trim();
if !list.is_empty() { if !list.is_empty() {
exceptions.push(list.to_string()); exceptions.push(list.into());
} }
} }
} }
@@ -452,9 +452,7 @@ impl AsyncProxyQuery {
if let Ok(mode_output) = mode_output if let Ok(mode_output) = mode_output
&& mode_output.status.success() && mode_output.status.success()
{ {
let mode = String::from_utf8_lossy(&mode_output.stdout) let mode = String::from_utf8_lossy(&mode_output.stdout).trim().into();
.trim()
.to_string();
if mode.contains("manual") { if mode.contains("manual") {
// 获取HTTP代理设置 // 获取HTTP代理设置
let host_result = Command::new("gsettings") let host_result = Command::new("gsettings")
@@ -475,7 +473,7 @@ impl AsyncProxyQuery {
.trim() .trim()
.trim_matches('\'') .trim_matches('\'')
.trim_matches('"') .trim_matches('"')
.to_string(); .into();
let port = String::from_utf8_lossy(&port_output.stdout) let port = String::from_utf8_lossy(&port_output.stdout)
.trim() .trim()
@@ -513,11 +511,11 @@ impl AsyncProxyQuery {
// 解析主机和端口 // 解析主机和端口
let (host, port) = if let Some(colon_pos) = url.rfind(':') { let (host, port) = if let Some(colon_pos) = url.rfind(':') {
let host = url[..colon_pos].to_string(); let host = url[..colon_pos].into();
let port = url[colon_pos + 1..].parse::<u16>().unwrap_or(8080); let port = url[colon_pos + 1..].parse::<u16>().unwrap_or(8080);
(host, port) (host, port)
} else { } else {
(url.to_string(), 8080) (url.into(), 8080)
}; };
if host.is_empty() { if host.is_empty() {

View File

@@ -86,7 +86,7 @@ impl WebDavClient {
|| verge.webdav_username.is_none() || verge.webdav_username.is_none()
|| verge.webdav_password.is_none() || verge.webdav_password.is_none()
{ {
let msg = "Unable to create web dav client, please make sure the webdav config is correct".to_string(); let msg: String = "Unable to create web dav client, please make sure the webdav config is correct".into();
return Err(anyhow::Error::msg(msg)); return Err(anyhow::Error::msg(msg));
} }
@@ -95,7 +95,7 @@ impl WebDavClient {
.webdav_url .webdav_url
.unwrap_or_default() .unwrap_or_default()
.trim_end_matches('/') .trim_end_matches('/')
.to_string(), .into(),
username: verge.webdav_username.unwrap_or_default(), username: verge.webdav_username.unwrap_or_default(),
password: verge.webdav_password.unwrap_or_default(), password: verge.webdav_password.unwrap_or_default(),
}; };

View File

@@ -272,13 +272,13 @@ impl CoreManager {
if has_error { if has_error {
logging!(info, Type::Config, "发现错误,开始处理错误信息"); logging!(info, Type::Config, "发现错误,开始处理错误信息");
let error_msg = if !stdout.is_empty() { let error_msg = if !stdout.is_empty() {
stdout.to_string() stdout.into()
} else if !stderr.is_empty() { } else if !stderr.is_empty() {
stderr.to_string() stderr.into()
} else if let Some(code) = output.status.code() { } else if let Some(code) = output.status.code() {
format!("验证进程异常退出,退出码: {code}") format!("验证进程异常退出,退出码: {code}")
} else { } else {
"验证进程被终止".to_string() "验证进程被终止".into()
}; };
logging!(info, Type::Config, "-------- 验证结束 --------"); logging!(info, Type::Config, "-------- 验证结束 --------");
@@ -350,7 +350,7 @@ impl CoreManager {
let error_msg = "Script must contain a main function"; let error_msg = "Script must contain a main function";
logging!(warn, Type::Config, "脚本缺少main函数: {}", path); logging!(warn, Type::Config, "脚本缺少main函数: {}", path);
//handle::Handle::notice_message("config_validate::script_missing_main", error_msg); //handle::Handle::notice_message("config_validate::script_missing_main", error_msg);
return Ok((false, error_msg.to_string())); return Ok((false, error_msg.into()));
} }
Ok((true, String::new())) Ok((true, String::new()))
@@ -441,7 +441,7 @@ impl CoreManager {
let process_name = if cfg!(windows) { let process_name = if cfg!(windows) {
format!("{target}.exe") format!("{target}.exe")
} else { } else {
target.to_string() target.into()
}; };
process_futures.push(self.find_processes_by_name(process_name, target)); process_futures.push(self.find_processes_by_name(process_name, target));
} }
@@ -917,7 +917,7 @@ impl CoreManager {
if clash_core.is_none() { if clash_core.is_none() {
let error_message = "Clash core should not be Null"; let error_message = "Clash core should not be Null";
logging!(error, Type::Core, "{}", error_message); logging!(error, Type::Core, "{}", error_message);
return Err(error_message.to_string()); return Err(error_message.into());
} }
let core = clash_core.as_ref().ok_or_else(|| { let core = clash_core.as_ref().ok_or_else(|| {
let msg = "Clash core should not be None"; let msg = "Clash core should not be None";

View File

@@ -55,13 +55,13 @@ impl Default for ProxyState {
pac_enabled: false, pac_enabled: false,
auto_proxy: Autoproxy { auto_proxy: Autoproxy {
enable: false, enable: false,
url: "".to_string(), url: "".into(),
}, },
sys_proxy: Sysproxy { sys_proxy: Sysproxy {
enable: false, enable: false,
host: "127.0.0.1".to_string(), host: "127.0.0.1".into(),
port: 7897, port: 7897,
bypass: "".to_string(), bypass: "".into(),
}, },
last_updated: std::time::Instant::now(), last_updated: std::time::Instant::now(),
is_healthy: true, is_healthy: true,
@@ -519,7 +519,7 @@ impl EventDrivenProxyManager {
verge verge
.proxy_host .proxy_host
.clone() .clone()
.unwrap_or_else(|| "127.0.0.1".to_string()) .unwrap_or_else(|| "127.0.0.1".into())
}; };
let pac_port = IVerge::get_singleton_port(); let pac_port = IVerge::get_singleton_port();
Autoproxy { Autoproxy {
@@ -534,7 +534,7 @@ impl EventDrivenProxyManager {
let proxy_host = verge_config.latest_ref().proxy_host.clone(); let proxy_host = verge_config.latest_ref().proxy_host.clone();
let port = verge_mixed_port.unwrap_or(Config::clash().await.latest_ref().get_mixed_port()); let port = verge_mixed_port.unwrap_or(Config::clash().await.latest_ref().get_mixed_port());
let proxy_host = proxy_host.unwrap_or_else(|| "127.0.0.1".to_string()); let proxy_host = proxy_host.unwrap_or_else(|| "127.0.0.1".into());
Sysproxy { Sysproxy {
enable: true, enable: true,

View File

@@ -330,7 +330,7 @@ async fn check_service_version() -> Result<String> {
return Err(anyhow::anyhow!(err_msg)); return Err(anyhow::anyhow!(err_msg));
} }
let version = response.data.unwrap_or("unknown".to_string()); let version = response.data.unwrap_or("unknown".into());
Ok(version) Ok(version)
}; };
@@ -361,9 +361,9 @@ pub(super) async fn start_with_existing_service(config_file: &PathBuf) -> Result
let payload = clash_verge_service_ipc::ClashConfig { let payload = clash_verge_service_ipc::ClashConfig {
core_config: CoreConfig { core_config: CoreConfig {
config_path: dirs::path_to_str(config_file)?.to_string(), config_path: dirs::path_to_str(config_file)?.into(),
core_path: dirs::path_to_str(&bin_path)?.to_string(), core_path: dirs::path_to_str(&bin_path)?.into(),
config_dir: dirs::path_to_str(&dirs::app_home_dir()?)?.to_string(), config_dir: dirs::path_to_str(&dirs::app_home_dir()?)?.into(),
}, },
log_config: service_writer_config().await?, log_config: service_writer_config().await?,
}; };

View File

@@ -39,11 +39,11 @@ async fn get_bypass() -> String {
}; };
let custom_bypass = match res { let custom_bypass = match res {
Some(bypass) => bypass, Some(bypass) => bypass,
None => "".to_string(), None => "".into(),
}; };
if custom_bypass.is_empty() { if custom_bypass.is_empty() {
DEFAULT_BYPASS.to_string() DEFAULT_BYPASS.into()
} else if use_default { } else if use_default {
format!("{DEFAULT_BYPASS},{custom_bypass}") format!("{DEFAULT_BYPASS},{custom_bypass}")
} else { } else {
@@ -180,11 +180,11 @@ impl Sysopt {
let args = if pac_enable { let args = if pac_enable {
let address = format!("http://{proxy_host}:{pac_port}/commands/pac"); let address = format!("http://{proxy_host}:{pac_port}/commands/pac");
vec!["pac".to_string(), address] vec!["pac".into(), address]
} else { } else {
let address = format!("{proxy_host}:{port}"); let address = format!("{proxy_host}:{port}");
let bypass = get_bypass().await; let bypass = get_bypass().await;
vec!["global".to_string(), address, bypass] vec!["global".into(), address, bypass]
}; };
execute_sysproxy_command(args).await?; execute_sysproxy_command(args).await?;
@@ -208,7 +208,7 @@ impl Sysopt {
log::warn!(target: "app", "重置代理时获取自动代理配置失败: {e}, 使用默认配置"); log::warn!(target: "app", "重置代理时获取自动代理配置失败: {e}, 使用默认配置");
Autoproxy { Autoproxy {
enable: false, enable: false,
url: "".to_string(), url: "".into(),
} }
} }
}; };
@@ -220,7 +220,7 @@ impl Sysopt {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
execute_sysproxy_command(vec!["set".to_string(), "1".to_string()]).await?; execute_sysproxy_command(vec!["set".into(), "1".into()]).await?;
} }
Ok(()) Ok(())

View File

@@ -457,9 +457,9 @@ impl Timer {
fn emit_update_event(_uid: &str, _is_start: bool) { fn emit_update_event(_uid: &str, _is_start: bool) {
{ {
if _is_start { if _is_start {
super::handle::Handle::notify_profile_update_started(_uid.to_string()); super::handle::Handle::notify_profile_update_started(_uid.into());
} else { } else {
super::handle::Handle::notify_profile_update_completed(_uid.to_string()); super::handle::Handle::notify_profile_update_completed(_uid.into());
} }
} }
} }

View File

@@ -83,7 +83,7 @@ impl TrayState {
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let tray_icon_colorful = verge.tray_icon.unwrap_or("monochrome".to_string()); let tray_icon_colorful = verge.tray_icon.unwrap_or("monochrome".into());
if tray_icon_colorful == "monochrome" { if tray_icon_colorful == "monochrome" {
( (
false, false,
@@ -117,7 +117,7 @@ impl TrayState {
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string()); let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".into());
if tray_icon_colorful == "monochrome" { if tray_icon_colorful == "monochrome" {
( (
false, false,
@@ -151,7 +151,7 @@ impl TrayState {
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string()); let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".into());
if tray_icon_colorful == "monochrome" { if tray_icon_colorful == "monochrome" {
( (
false, false,
@@ -349,7 +349,7 @@ impl Tray {
(false, false) => TrayState::get_common_tray_icon().await, (false, false) => TrayState::get_common_tray_icon().await,
}; };
let colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string()); let colorful = verge.tray_icon.clone().unwrap_or("monochrome".into());
let is_colorful = colorful == "colorful"; let is_colorful = colorful == "colorful";
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?)); let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?));
@@ -427,7 +427,7 @@ impl Tray {
map map
}; };
let mut current_profile_name = "None".to_string(); let mut current_profile_name = "None".into();
{ {
let profiles = Config::profiles().await; let profiles = Config::profiles().await;
let profiles = profiles.latest_ref(); let profiles = profiles.latest_ref();
@@ -447,7 +447,7 @@ impl Tray {
let profile_text = t("Profile").await; let profile_text = t("Profile").await;
let v = env!("CARGO_PKG_VERSION"); let v = env!("CARGO_PKG_VERSION");
let reassembled_version = v.split_once('+').map_or(v.to_string(), |(main, rest)| { let reassembled_version = v.split_once('+').map_or(v.into(), |(main, rest)| {
format!("{main}+{}", rest.split('.').next().unwrap_or("")) format!("{main}+{}", rest.split('.').next().unwrap_or(""))
}); });
@@ -617,7 +617,7 @@ async fn create_tray_menu(
.filter_map(|item| { .filter_map(|item| {
let mut parts = item.split(','); let mut parts = item.split(',');
match (parts.next(), parts.next()) { match (parts.next(), parts.next()) {
(Some(func), Some(key)) => Some((func.to_string(), key.to_string())), (Some(func), Some(key)) => Some((func.into(), key.into())),
_ => None, _ => None,
} }
}) })
@@ -690,11 +690,11 @@ async fn create_tray_menu(
.get(proxy_str) .get(proxy_str)
.and_then(|h| h.history.last()) .and_then(|h| h.history.last())
.map(|h| match h.delay { .map(|h| match h.delay {
0 => "-ms".to_string(), 0 => "-ms".into(),
delay if delay >= 10000 => "-ms".to_string(), delay if delay >= 10000 => "-ms".into(),
_ => format!("{}ms", h.delay), _ => format!("{}ms", h.delay),
}) })
.unwrap_or_else(|| "-ms".to_string()); .unwrap_or_else(|| "-ms".into());
let display_text = format!("{} | {}", proxy_str, delay_text); let display_text = format!("{} | {}", proxy_str, delay_text);
@@ -773,7 +773,7 @@ async fn create_tray_menu(
.iter() .iter()
.filter_map(|group| group.get("name")) .filter_map(|group| group.get("name"))
.filter_map(|name| name.as_str()) .filter_map(|name| name.as_str())
.map(|name| name.to_string()) .map(|name| name.into())
.collect::<Vec<String>>() .collect::<Vec<String>>()
}) })
.unwrap_or_default() .unwrap_or_default()

View File

@@ -72,7 +72,7 @@ pub async fn copy_clash_env() {
.latest_ref() .latest_ref()
.proxy_host .proxy_host
.clone() .clone()
.unwrap_or_else(|| "127.0.0.1".to_string()), .unwrap_or_else(|| "127.0.0.1".into()),
}; };
let app_handle = handle::Handle::app_handle(); let app_handle = handle::Handle::app_handle();
@@ -96,7 +96,7 @@ pub async fn copy_clash_env() {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let default = "powershell"; let default = "powershell";
default.to_string() default.into()
} }
}; };

View File

@@ -5,7 +5,7 @@ fn main() {
// Check for --no-tray command line argument // Check for --no-tray command line argument
let args: Vec<String> = std::env::args().collect(); let args: Vec<String> = std::env::args().collect();
if args.contains(&"--no-tray".to_string()) { if args.contains(&"--no-tray".into()) {
unsafe { unsafe {
std::env::set_var("CLASH_VERGE_DISABLE_TRAY", "1"); std::env::set_var("CLASH_VERGE_DISABLE_TRAY", "1");
} }

View File

@@ -108,7 +108,7 @@ pub fn find_target_icons(target: &str) -> Result<Option<String>> {
match matching_files.first() { match matching_files.first() {
Some(first_path) => { Some(first_path) => {
let first = path_to_str(first_path)?; let first = path_to_str(first_path)?;
Ok(Some(first.to_string())) Ok(Some(first.into()))
} }
None => Ok(None), None => Ok(None),
} }

View File

@@ -22,13 +22,13 @@ pub fn get_supported_languages() -> Vec<String> {
if let Some(file_name) = entry.file_name().to_str() if let Some(file_name) = entry.file_name().to_str()
&& let Some(lang) = file_name.strip_suffix(".json") && let Some(lang) = file_name.strip_suffix(".json")
{ {
languages.push(lang.to_string()); languages.push(lang.into());
} }
} }
} }
if languages.is_empty() { if languages.is_empty() {
languages.push(DEFAULT_LANGUAGE.to_string()); languages.push(DEFAULT_LANGUAGE.into());
} }
languages languages
} }
@@ -52,7 +52,7 @@ fn get_system_language() -> String {
.map(|locale| locale.to_lowercase()) .map(|locale| locale.to_lowercase())
.and_then(|locale| locale.split(['_', '-']).next().map(String::from)) .and_then(|locale| locale.split(['_', '-']).next().map(String::from))
.filter(|lang| get_supported_languages().contains(lang)) .filter(|lang| get_supported_languages().contains(lang))
.unwrap_or_else(|| DEFAULT_LANGUAGE.to_string()) .unwrap_or_else(|| DEFAULT_LANGUAGE.into())
} }
pub async fn t(key: &str) -> String { pub async fn t(key: &str) -> String {
@@ -69,7 +69,7 @@ pub async fn t(key: &str) -> String {
&& cache.0 == current_lang && cache.0 == current_lang
&& let Some(text) = cache.1.get(key).and_then(|val| val.as_str()) && let Some(text) = cache.1.get(key).and_then(|val| val.as_str())
{ {
return text.to_string(); return text.into();
} }
} }
@@ -79,7 +79,7 @@ pub async fn t(key: &str) -> String {
*cache = (current_lang.clone(), new_json); *cache = (current_lang.clone(), new_json);
if let Some(text) = cache.1.get(key).and_then(|val| val.as_str()) { if let Some(text) = cache.1.get(key).and_then(|val| val.as_str()) {
return text.to_string(); return text.into();
} }
} }
@@ -87,12 +87,12 @@ pub async fn t(key: &str) -> String {
&& let Some(default_json) = load_lang_file(DEFAULT_LANGUAGE) && let Some(default_json) = load_lang_file(DEFAULT_LANGUAGE)
&& let Ok(mut cache) = TRANSLATIONS.write() && let Ok(mut cache) = TRANSLATIONS.write()
{ {
*cache = (DEFAULT_LANGUAGE.to_string(), default_json); *cache = (DEFAULT_LANGUAGE.into(), default_json);
if let Some(text) = cache.1.get(key).and_then(|val| val.as_str()) { if let Some(text) = cache.1.get(key).and_then(|val| val.as_str()) {
return text.to_string(); return text.into();
} }
} }
key.to_string() key.into()
} }

View File

@@ -102,7 +102,7 @@ pub async fn service_writer_config() -> Result<WriterConfig> {
verge.app_log_max_count.unwrap_or(8), verge.app_log_max_count.unwrap_or(8),
) )
}; };
let service_log_dir = dirs::path_to_str(&service_log_dir()?)?.to_string(); let service_log_dir = dirs::path_to_str(&service_log_dir()?)?.into();
Ok(WriterConfig { Ok(WriterConfig {
directory: service_log_dir, directory: service_log_dir,
@@ -437,7 +437,7 @@ pub async fn init_resources() -> Result<()> {
}; };
if src_path.exists() && !dest_path.exists() { if src_path.exists() && !dest_path.exists() {
handle_copy(src_path.clone(), dest_path.clone(), file.to_string()).await; handle_copy(src_path.clone(), dest_path.clone(), (*file).into()).await;
continue; continue;
} }
@@ -447,12 +447,12 @@ pub async fn init_resources() -> Result<()> {
match (src_modified, dest_modified) { match (src_modified, dest_modified) {
(Ok(src_modified), Ok(dest_modified)) => { (Ok(src_modified), Ok(dest_modified)) => {
if src_modified > dest_modified { if src_modified > dest_modified {
handle_copy(src_path.clone(), dest_path.clone(), file.to_string()).await; handle_copy(src_path.clone(), dest_path.clone(), (*file).into()).await;
} }
} }
_ => { _ => {
logging!(debug, Type::Setup, "failed to get modified '{}'", file); logging!(debug, Type::Setup, "failed to get modified '{}'", file);
handle_copy(src_path.clone(), dest_path.clone(), file.to_string()).await; handle_copy(src_path.clone(), dest_path.clone(), (*file).into()).await;
} }
}; };
} }
@@ -506,7 +506,7 @@ pub async fn startup_script() -> Result<()> {
let script_path = { let script_path = {
let verge = Config::verge().await; let verge = Config::verge().await;
let verge = verge.latest_ref(); let verge = verge.latest_ref();
verge.startup_script.clone().unwrap_or("".to_string()) verge.startup_script.clone().unwrap_or("".into())
}; };
if script_path.is_empty() { if script_path.is_empty() {

View File

@@ -75,8 +75,8 @@ pub fn embed_server() {
} else { } else {
logging!(error, Type::Window, "轻量模式退出失败,无法恢复应用窗口"); logging!(error, Type::Window, "轻量模式退出失败,无法恢复应用窗口");
}; };
Ok::<_, warp::Rejection>(warp::reply::with_status( Ok::<_, warp::Rejection>(warp::reply::with_status::<String>(
"ok".to_string(), "ok".into(),
warp::http::StatusCode::OK, warp::http::StatusCode::OK,
)) ))
}); });
@@ -88,7 +88,7 @@ pub fn embed_server() {
.latest_ref() .latest_ref()
.pac_file_content .pac_file_content
.clone() .clone()
.unwrap_or(DEFAULT_PAC.to_string()); .unwrap_or(DEFAULT_PAC.into());
let mixed_port = verge_config let mixed_port = verge_config
.latest_ref() .latest_ref()
@@ -115,7 +115,7 @@ pub fn embed_server() {
tokio::task::spawn_local(async move { tokio::task::spawn_local(async move {
logging_error!(Type::Setup, resolve::resolve_scheme(param).await); logging_error!(Type::Setup, resolve::resolve_scheme(param).await);
}); });
warp::reply::with_status("ok".to_string(), warp::http::StatusCode::OK) warp::reply::with_status::<String>("ok".into(), warp::http::StatusCode::OK)
}); });
let commands = visible.or(scheme).or(pac); let commands = visible.or(scheme).or(pac);