refactor: reduce clone operation (#5268)

* refactor: optimize item handling and improve profile management

* refactor: update IVerge references to use references instead of owned values

* refactor: update patch_verge to use data_ref for improved data handling

* refactor: move handle_copy function to improve resource initialization logic

* refactor: update profile handling to use references for improved memory efficiency

* refactor: simplify get_item method and update profile item retrieval to use string slices

* refactor: update profile validation and patching to use references for improved performance

* refactor: update profile functions to use references for improved performance and memory efficiency

* refactor: update profile patching functions to use references for improved memory efficiency

* refactor: simplify merge function in PrfOption to enhance readability

* refactor: update change_core function to accept a reference for improved memory efficiency

* refactor: update PrfItem and profile functions to use references for improved memory efficiency

* refactor: update resolve_scheme function to accept a reference for improved memory efficiency

* refactor: update resolve_scheme function to accept a string slice for improved flexibility

* refactor: simplify update_profile parameters and logic
This commit is contained in:
Tunglies
2025-11-01 20:03:56 +08:00
committed by GitHub
parent 73e53eb33f
commit 9370a56337
24 changed files with 258 additions and 251 deletions

View File

@@ -29,6 +29,11 @@ impl<T: Clone + ToOwned> From<T> for Draft<T> {
/// - `apply`: Commits the draft data, replacing the committed data and returning the old committed value if a draft existed.
/// - `discard`: Discards the draft data and returns it if it existed.
impl<T: Clone + ToOwned> Draft<Box<T>> {
/// 正式数据视图
pub fn data_ref(&self) -> MappedRwLockReadGuard<'_, Box<T>> {
RwLockReadGuard::map(self.inner.read(), |inner| &inner.0)
}
/// 可写正式数据
pub fn data_mut(&self) -> MappedRwLockWriteGuard<'_, Box<T>> {
RwLockWriteGuard::map(self.inner.write(), |inner| &mut inner.0)

View File

@@ -429,26 +429,8 @@ pub async fn init_resources() -> Result<()> {
let src_path = res_dir.join(file);
let dest_path = app_dir.join(file);
let handle_copy = |src: PathBuf, dest: PathBuf, file: String| async move {
match fs::copy(&src, &dest).await {
Ok(_) => {
logging!(debug, Type::Setup, "resources copied '{}'", file);
}
Err(err) => {
logging!(
error,
Type::Setup,
"failed to copy resources '{}' to '{:?}', {}",
file,
dest,
err
);
}
};
};
if src_path.exists() && !dest_path.exists() {
handle_copy(src_path.clone(), dest_path.clone(), (*file).into()).await;
handle_copy(&src_path, &dest_path, file).await;
continue;
}
@@ -458,12 +440,12 @@ pub async fn init_resources() -> Result<()> {
match (src_modified, dest_modified) {
(Ok(src_modified), Ok(dest_modified)) => {
if src_modified > dest_modified {
handle_copy(src_path.clone(), dest_path.clone(), (*file).into()).await;
handle_copy(&src_path, &dest_path, file).await;
}
}
_ => {
logging!(debug, Type::Setup, "failed to get modified '{}'", file);
handle_copy(src_path.clone(), dest_path.clone(), (*file).into()).await;
handle_copy(&src_path, &dest_path, file).await;
}
};
}
@@ -563,3 +545,21 @@ pub async fn startup_script() -> Result<()> {
Ok(())
}
async fn handle_copy(src: &PathBuf, dest: &PathBuf, file: &str) {
match fs::copy(src, dest).await {
Ok(_) => {
logging!(debug, Type::Setup, "resources copied '{}'", file);
}
Err(err) => {
logging!(
error,
Type::Setup,
"failed to copy resources '{}' to '{:?}', {}",
file,
dest,
err
);
}
};
}

View File

@@ -1,5 +1,4 @@
use anyhow::Result;
use smartstring::alias::String;
use crate::{
config::Config,
@@ -99,7 +98,7 @@ pub(super) async fn resolve_setup_logger() {
logging_error!(Type::Setup, init::init_logger().await);
}
pub async fn resolve_scheme(param: String) -> Result<()> {
pub async fn resolve_scheme(param: &str) -> Result<()> {
logging_error!(Type::Setup, scheme::resolve_scheme(param).await);
Ok(())
}

View File

@@ -3,9 +3,14 @@ use percent_encoding::percent_decode_str;
use smartstring::alias::String;
use tauri::Url;
use crate::{config::PrfItem, core::handle, logging, logging_error, utils::logging::Type};
use crate::{
config::{PrfItem, profiles},
core::handle,
logging, logging_error,
utils::logging::Type,
};
pub(super) async fn resolve_scheme(param: String) -> Result<()> {
pub(super) async fn resolve_scheme(param: &str) -> Result<()> {
log::info!(target:"app", "received deep link: {param}");
let param_str = if param.starts_with("[") && param.len() > 4 {
@@ -13,7 +18,7 @@ pub(super) async fn resolve_scheme(param: String) -> Result<()> {
.get(2..param.len() - 2)
.ok_or_else(|| anyhow::anyhow!("Invalid string slice boundaries"))?
} else {
param.as_str()
param
};
// 解析 URL
@@ -25,10 +30,11 @@ pub(super) async fn resolve_scheme(param: String) -> Result<()> {
};
if link_parsed.scheme() == "clash" || link_parsed.scheme() == "clash-verge" {
let name = link_parsed
let name_owned: Option<String> = link_parsed
.query_pairs()
.find(|(key, _)| key == "name")
.map(|(_, value)| value.into());
.map(|(_, value)| value.into_owned().into());
let name = name_owned.as_ref();
let url_param = if let Some(query) = link_parsed.query() {
let prefix = "url=";
@@ -43,10 +49,10 @@ pub(super) async fn resolve_scheme(param: String) -> Result<()> {
};
match url_param {
Some(url) => {
Some(ref url) => {
log::info!(target:"app", "decoded subscription url: {url}");
match PrfItem::from_url(url.as_ref(), name, None, None).await {
Ok(item) => {
match PrfItem::from_url(url, name, None, None).await {
Ok(mut item) => {
let uid = match item.uid.clone() {
Some(uid) => uid,
None => {
@@ -58,7 +64,7 @@ pub(super) async fn resolve_scheme(param: String) -> Result<()> {
return Ok(());
}
};
let result = crate::config::profiles::profiles_append_item_safe(item).await;
let result = profiles::profiles_append_item_safe(&mut item).await;
logging_error!(
Type::Config,
"failed to import subscription url: {:?}",

View File

@@ -21,16 +21,14 @@ const MINIMAL_HEIGHT: f64 = 520.0;
pub async fn build_new_window() -> Result<WebviewWindow, String> {
let app_handle = handle::Handle::app_handle();
let start_page = Config::verge()
.await
.latest_ref()
.start_page
.clone()
.unwrap_or_else(|| "/".into());
let config = Config::verge().await;
let latest = config.latest_ref();
let start_page = latest.start_page.as_deref().unwrap_or("/");
match tauri::WebviewWindowBuilder::new(
app_handle,
"main", /* the unique window label */
tauri::WebviewUrl::App(start_page.as_str().into()),
tauri::WebviewUrl::App(start_page.into()),
)
.title("Clash Verge")
.center()

View File

@@ -107,9 +107,8 @@ pub fn embed_server() {
let scheme = warp::path!("commands" / "scheme")
.and(warp::query::<QueryParam>())
.map(|query: QueryParam| {
let param = query.param.clone();
tokio::task::spawn_local(async move {
logging_error!(Type::Setup, resolve::resolve_scheme(param).await);
logging_error!(Type::Setup, resolve::resolve_scheme(&query.param).await);
});
warp::reply::with_status::<std::string::String>(
"ok".to_string(),