mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +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:
@@ -8,6 +8,7 @@ use crate::{
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use backoff::{Error as BackoffError, ExponentialBackoff};
|
||||
use smartstring::alias::String;
|
||||
use std::path::PathBuf;
|
||||
use tokio::sync::OnceCell;
|
||||
use tokio::time::sleep;
|
||||
@@ -122,7 +123,7 @@ impl Config {
|
||||
|
||||
if let Some((msg_type, msg_content)) = validation_result {
|
||||
sleep(timing::STARTUP_ERROR_DELAY).await;
|
||||
handle::Handle::notice_message(msg_type, &msg_content);
|
||||
handle::Handle::notice_message(msg_type, msg_content);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::utils::{
|
||||
use anyhow::{Context, Result, bail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml_ng::Mapping;
|
||||
use smartstring::alias::String;
|
||||
use std::{fs, time::Duration};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
||||
@@ -179,8 +180,8 @@ impl PrfItem {
|
||||
file_data: Option<String>,
|
||||
option: Option<PrfOption>,
|
||||
) -> Result<PrfItem> {
|
||||
let uid = help::get_uid("L");
|
||||
let file = format!("{uid}.yaml");
|
||||
let uid = help::get_uid("L").into();
|
||||
let file = format!("{uid}.yaml").into();
|
||||
let opt_ref = option.as_ref();
|
||||
let update_interval = opt_ref.and_then(|o| o.update_interval);
|
||||
let mut merge = opt_ref.and_then(|o| o.merge.clone());
|
||||
@@ -352,9 +353,9 @@ impl PrfItem {
|
||||
None => None,
|
||||
};
|
||||
|
||||
let uid = help::get_uid("R");
|
||||
let file = format!("{uid}.yaml");
|
||||
let name = name.unwrap_or(filename.unwrap_or("Remote File".into()));
|
||||
let uid = help::get_uid("R").into();
|
||||
let file = format!("{uid}.yaml").into();
|
||||
let name = name.unwrap_or(filename.unwrap_or("Remote File".into()).into());
|
||||
let data = resp.text_with_charset()?;
|
||||
|
||||
// process the charset "UTF-8 with BOM"
|
||||
@@ -422,13 +423,13 @@ impl PrfItem {
|
||||
/// ## Merge type (enhance)
|
||||
/// create the enhanced item by using `merge` rule
|
||||
pub fn from_merge(uid: Option<String>) -> Result<PrfItem> {
|
||||
let mut id = help::get_uid("m");
|
||||
let mut id = help::get_uid("m").into();
|
||||
let mut template = tmpl::ITEM_MERGE_EMPTY.into();
|
||||
if let Some(uid) = uid {
|
||||
id = uid;
|
||||
template = tmpl::ITEM_MERGE.into();
|
||||
}
|
||||
let file = format!("{id}.yaml");
|
||||
let file = format!("{id}.yaml").into();
|
||||
|
||||
Ok(PrfItem {
|
||||
uid: Some(id),
|
||||
@@ -449,11 +450,11 @@ impl PrfItem {
|
||||
/// ## Script type (enhance)
|
||||
/// create the enhanced item by using javascript quick.js
|
||||
pub fn from_script(uid: Option<String>) -> Result<PrfItem> {
|
||||
let mut id = help::get_uid("s");
|
||||
let mut id = help::get_uid("s").into();
|
||||
if let Some(uid) = uid {
|
||||
id = uid;
|
||||
}
|
||||
let file = format!("{id}.js"); // js ext
|
||||
let file = format!("{id}.js").into(); // js ext
|
||||
|
||||
Ok(PrfItem {
|
||||
uid: Some(id),
|
||||
@@ -473,8 +474,8 @@ impl PrfItem {
|
||||
|
||||
/// ## Rules type (enhance)
|
||||
pub fn from_rules() -> Result<PrfItem> {
|
||||
let uid = help::get_uid("r");
|
||||
let file = format!("{uid}.yaml"); // yaml ext
|
||||
let uid = help::get_uid("r").into();
|
||||
let file = format!("{uid}.yaml").into(); // yaml ext
|
||||
|
||||
Ok(PrfItem {
|
||||
uid: Some(uid),
|
||||
@@ -494,8 +495,8 @@ impl PrfItem {
|
||||
|
||||
/// ## Proxies type (enhance)
|
||||
pub fn from_proxies() -> Result<PrfItem> {
|
||||
let uid = help::get_uid("p");
|
||||
let file = format!("{uid}.yaml"); // yaml ext
|
||||
let uid = help::get_uid("p").into();
|
||||
let file = format!("{uid}.yaml").into(); // yaml ext
|
||||
|
||||
Ok(PrfItem {
|
||||
uid: Some(uid),
|
||||
@@ -515,8 +516,8 @@ impl PrfItem {
|
||||
|
||||
/// ## Groups type (enhance)
|
||||
pub fn from_groups() -> Result<PrfItem> {
|
||||
let uid = help::get_uid("g");
|
||||
let file = format!("{uid}.yaml"); // yaml ext
|
||||
let uid = help::get_uid("g").into();
|
||||
let file = format!("{uid}.yaml").into(); // yaml ext
|
||||
|
||||
Ok(PrfItem {
|
||||
uid: Some(uid),
|
||||
@@ -540,8 +541,9 @@ impl PrfItem {
|
||||
.file
|
||||
.clone()
|
||||
.ok_or_else(|| anyhow::anyhow!("could not find the file"))?;
|
||||
let path = dirs::app_profiles_dir()?.join(file);
|
||||
fs::read_to_string(path).context("failed to read the file")
|
||||
let path = dirs::app_profiles_dir()?.join(file.as_str());
|
||||
let content = fs::read_to_string(path).context("failed to read the file")?;
|
||||
Ok(content.into())
|
||||
}
|
||||
|
||||
/// save the file data
|
||||
@@ -550,7 +552,7 @@ impl PrfItem {
|
||||
.file
|
||||
.clone()
|
||||
.ok_or_else(|| anyhow::anyhow!("could not find the file"))?;
|
||||
let path = dirs::app_profiles_dir()?.join(file);
|
||||
let path = dirs::app_profiles_dir()?.join(file.as_str());
|
||||
fs::write(path, data.as_bytes()).context("failed to save the file")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::utils::{
|
||||
use anyhow::{Context, Result, bail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml_ng::Mapping;
|
||||
use smartstring::alias::String;
|
||||
use std::collections::HashSet;
|
||||
use tokio::fs;
|
||||
|
||||
@@ -47,7 +48,7 @@ impl IProfiles {
|
||||
if let Some(items) = profiles.items.as_mut() {
|
||||
for item in items.iter_mut() {
|
||||
if item.uid.is_none() {
|
||||
item.uid = Some(help::get_uid("d"));
|
||||
item.uid = Some(help::get_uid("d").into());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,7 +143,7 @@ impl IProfiles {
|
||||
let file = item.file.clone().ok_or_else(|| {
|
||||
anyhow::anyhow!("file field is required when file_data is provided")
|
||||
})?;
|
||||
let path = dirs::app_profiles_dir()?.join(&file);
|
||||
let path = dirs::app_profiles_dir()?.join(file.as_str());
|
||||
|
||||
fs::write(&path, file_data.as_bytes())
|
||||
.await
|
||||
@@ -240,13 +241,13 @@ impl IProfiles {
|
||||
// move the field value after save
|
||||
if let Some(file_data) = item.file_data.take() {
|
||||
let file = each.file.take();
|
||||
let file =
|
||||
file.unwrap_or(item.file.take().unwrap_or(format!("{}.yaml", &uid)));
|
||||
let file = file
|
||||
.unwrap_or(item.file.take().unwrap_or(format!("{}.yaml", &uid).into()));
|
||||
|
||||
// the file must exists
|
||||
each.file = Some(file.clone());
|
||||
|
||||
let path = dirs::app_profiles_dir()?.join(&file);
|
||||
let path = dirs::app_profiles_dir()?.join(file.as_str());
|
||||
|
||||
fs::write(&path, file_data.as_bytes())
|
||||
.await
|
||||
@@ -291,7 +292,7 @@ impl IProfiles {
|
||||
&& let Some(file) = items.remove(index).file
|
||||
{
|
||||
let _ = dirs::app_profiles_dir()?
|
||||
.join(file)
|
||||
.join(file.as_str())
|
||||
.remove_if_exists()
|
||||
.await;
|
||||
}
|
||||
@@ -306,7 +307,7 @@ impl IProfiles {
|
||||
&& let Some(file) = items.remove(index).file
|
||||
{
|
||||
let _ = dirs::app_profiles_dir()?
|
||||
.join(file)
|
||||
.join(file.as_str())
|
||||
.remove_if_exists()
|
||||
.await;
|
||||
}
|
||||
@@ -321,7 +322,7 @@ impl IProfiles {
|
||||
&& let Some(file) = items.remove(index).file
|
||||
{
|
||||
let _ = dirs::app_profiles_dir()?
|
||||
.join(file)
|
||||
.join(file.as_str())
|
||||
.remove_if_exists()
|
||||
.await;
|
||||
}
|
||||
@@ -336,7 +337,7 @@ impl IProfiles {
|
||||
&& let Some(file) = items.remove(index).file
|
||||
{
|
||||
let _ = dirs::app_profiles_dir()?
|
||||
.join(file)
|
||||
.join(file.as_str())
|
||||
.remove_if_exists()
|
||||
.await;
|
||||
}
|
||||
@@ -351,7 +352,7 @@ impl IProfiles {
|
||||
&& let Some(file) = items.remove(index).file
|
||||
{
|
||||
let _ = dirs::app_profiles_dir()?
|
||||
.join(file)
|
||||
.join(file.as_str())
|
||||
.remove_if_exists()
|
||||
.await;
|
||||
}
|
||||
@@ -366,7 +367,7 @@ impl IProfiles {
|
||||
&& let Some(file) = items.remove(index).file
|
||||
{
|
||||
let _ = dirs::app_profiles_dir()?
|
||||
.join(file)
|
||||
.join(file.as_str())
|
||||
.remove_if_exists()
|
||||
.await;
|
||||
}
|
||||
@@ -392,7 +393,7 @@ impl IProfiles {
|
||||
(Some(current), Some(items)) => {
|
||||
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
|
||||
let file_path = match item.file.as_ref() {
|
||||
Some(file) => dirs::app_profiles_dir()?.join(file),
|
||||
Some(file) => dirs::app_profiles_dir()?.join(file.as_str()),
|
||||
None => bail!("failed to get the file field"),
|
||||
};
|
||||
return help::read_mapping(&file_path).await;
|
||||
@@ -544,7 +545,7 @@ impl IProfiles {
|
||||
log::info!(target: "app", "已清理冗余文件: {file_name}");
|
||||
}
|
||||
Err(e) => {
|
||||
failed_deletions.push(format!("{file_name}: {e}"));
|
||||
failed_deletions.push(format!("{file_name}: {e}").into());
|
||||
log::warn!(target: "app", "清理文件失败: {file_name} - {e}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use crate::enhance::field::use_keys;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml_ng::{Mapping, Value};
|
||||
use smartstring::alias::String;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct IRuntime {
|
||||
pub config: Option<Mapping>,
|
||||
@@ -30,15 +32,15 @@ impl IRuntime {
|
||||
let patch_tun = patch.get("tun");
|
||||
if patch_tun.is_some() {
|
||||
let tun = config.get("tun");
|
||||
let mut tun = tun.map_or(Mapping::new(), |val| {
|
||||
let mut tun: Mapping = tun.map_or(Mapping::new(), |val| {
|
||||
val.as_mapping().cloned().unwrap_or(Mapping::new())
|
||||
});
|
||||
let patch_tun = patch_tun.map_or(Mapping::new(), |val| {
|
||||
val.as_mapping().cloned().unwrap_or(Mapping::new())
|
||||
});
|
||||
use_keys(&patch_tun).into_iter().for_each(|key| {
|
||||
if let Some(value) = patch_tun.get(&key).to_owned() {
|
||||
tun.insert(key.into(), value.clone());
|
||||
if let Some(value) = patch_tun.get(key.as_str()) {
|
||||
tun.insert(Value::from(key.as_str()), value.clone());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::{
|
||||
use anyhow::Result;
|
||||
use log::LevelFilter;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smartstring::alias::String;
|
||||
|
||||
/// ### `verge.yaml` schema
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
@@ -322,7 +323,7 @@ impl IVerge {
|
||||
|
||||
fn get_system_language() -> String {
|
||||
let sys_lang = sys_locale::get_locale()
|
||||
.unwrap_or_else(|| String::from("en"))
|
||||
.unwrap_or_else(|| "en".into())
|
||||
.to_lowercase();
|
||||
|
||||
let lang_code = sys_lang.split(['_', '-']).next().unwrap_or("en");
|
||||
|
||||
Reference in New Issue
Block a user