chore: git hooks for linter and formatter

This commit is contained in:
Tunglies
2025-03-13 12:51:20 +08:00
parent 124934b012
commit b57c6e408a
50 changed files with 479 additions and 375 deletions

View File

@@ -75,40 +75,41 @@ pub fn get_app_dir() -> CmdResult<String> {
pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String> {
let icon_cache_dir = wrap_err!(dirs::app_home_dir())?.join("icons").join("cache");
let icon_path = icon_cache_dir.join(&name);
// 如果文件已存在,直接返回路径
if icon_path.exists() {
return Ok(icon_path.to_string_lossy().to_string());
}
// 确保缓存目录存在
if !icon_cache_dir.exists() {
let _ = std::fs::create_dir_all(&icon_cache_dir);
}
// 使用临时文件名来下载
let temp_path = icon_cache_dir.join(format!("{}.downloading", &name));
// 下载文件到临时位置
let response = wrap_err!(reqwest::get(&url).await)?;
// 检查内容类型是否为图片
let content_type = response.headers()
let content_type = response
.headers()
.get(reqwest::header::CONTENT_TYPE)
.and_then(|v| v.to_str().ok())
.unwrap_or("");
let is_image = content_type.starts_with("image/");
// 获取响应内容
let content = wrap_err!(response.bytes().await)?;
// 检查内容是否为HTML (针对CDN错误页面)
let is_html = content.len() > 15 &&
(content.starts_with(b"<!DOCTYPE html") ||
content.starts_with(b"<html") ||
content.starts_with(b"<?xml"));
let is_html = content.len() > 15
&& (content.starts_with(b"<!DOCTYPE html")
|| content.starts_with(b"<html")
|| content.starts_with(b"<?xml"));
// 只有当内容确实是图片时才保存
if is_image && !is_html {
{
@@ -122,14 +123,14 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
}
}
};
wrap_err!(std::io::copy(&mut content.as_ref(), &mut file))?;
}
// 再次检查目标文件是否已存在,避免重命名覆盖其他线程已完成的文件
if !icon_path.exists() {
match std::fs::rename(&temp_path, &icon_path) {
Ok(_) => {},
Ok(_) => {}
Err(_) => {
let _ = std::fs::remove_file(&temp_path);
if icon_path.exists() {
@@ -140,11 +141,11 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
} else {
let _ = std::fs::remove_file(&temp_path);
}
Ok(icon_path.to_string_lossy().to_string())
} else {
let _ = std::fs::remove_file(&temp_path);
Err(format!("下载的内容不是有效图片: {}", url).into())
Err(format!("下载的内容不是有效图片: {}", url))
}
}
@@ -158,8 +159,7 @@ pub struct IconInfo {
/// 复制图标文件
#[tauri::command]
pub fn copy_icon_file(path: String, icon_info: IconInfo) -> CmdResult<String> {
use std::fs;
use std::path::Path;
use std::{fs, path::Path};
let file_path = Path::new(&path);

View File

@@ -24,7 +24,8 @@ pub async fn patch_clash_config(payload: Mapping) -> CmdResult {
/// 修改Clash模式
#[tauri::command]
pub async fn patch_clash_mode(payload: String) -> CmdResult {
Ok(feat::change_clash_mode(payload))
feat::change_clash_mode(payload);
Ok(())
}
/// 切换Clash核心
@@ -98,9 +99,11 @@ pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
/// 应用或撤销DNS配置
#[tauri::command]
pub fn apply_dns_config(apply: bool) -> CmdResult {
use crate::config::Config;
use crate::core::{handle, CoreManager};
use crate::utils::dirs;
use crate::{
config::Config,
core::{handle, CoreManager},
utils::dirs,
};
use tauri::async_runtime;
// 使用spawn来处理异步操作

View File

@@ -4,29 +4,29 @@ use anyhow::Result;
pub type CmdResult<T = ()> = Result<T, String>;
// Command modules
pub mod profile;
pub mod validate;
pub mod uwp;
pub mod webdav;
pub mod app;
pub mod network;
pub mod clash;
pub mod verge;
pub mod network;
pub mod profile;
pub mod proxy;
pub mod runtime;
pub mod save_profile;
pub mod system;
pub mod proxy;
pub mod uwp;
pub mod validate;
pub mod verge;
pub mod webdav;
// Re-export all command functions for backwards compatibility
pub use profile::*;
pub use validate::*;
pub use uwp::*;
pub use webdav::*;
pub use app::*;
pub use network::*;
pub use clash::*;
pub use verge::*;
pub use network::*;
pub use profile::*;
pub use proxy::*;
pub use runtime::*;
pub use save_profile::*;
pub use system::*;
pub use proxy::*;
pub use uwp::*;
pub use validate::*;
pub use verge::*;
pub use webdav::*;

View File

@@ -1,8 +1,8 @@
use crate::wrap_err;
use super::CmdResult;
use sysproxy::{Autoproxy, Sysproxy};
use serde_yaml::Mapping;
use crate::wrap_err;
use network_interface::NetworkInterface;
use serde_yaml::Mapping;
use sysproxy::{Autoproxy, Sysproxy};
/// get the system proxy
#[tauri::command]
@@ -46,8 +46,7 @@ pub fn get_network_interfaces() -> Vec<String> {
/// 获取网络接口详细信息
#[tauri::command]
pub fn get_network_interfaces_info() -> CmdResult<Vec<NetworkInterface>> {
use network_interface::NetworkInterface;
use network_interface::NetworkInterfaceConfig;
use network_interface::{NetworkInterface, NetworkInterfaceConfig};
let names = get_network_interfaces();
let interfaces = wrap_err!(NetworkInterface::show())?;

View File

@@ -1,11 +1,11 @@
use super::CmdResult;
use crate::{
config::*,
core::*,
feat,
feat, log_err, ret_err,
utils::{dirs, help},
log_err, ret_err, wrap_err,
wrap_err,
};
use super::CmdResult;
/// 获取配置文件列表
#[tauri::command]
@@ -31,7 +31,7 @@ pub async fn enhance_profiles() -> CmdResult {
}
Err(e) => {
println!("[enhance_profiles] 更新过程发生错误: {}", e);
handle::Handle::notice_message("config_validate::process_terminated", &e.to_string());
handle::Handle::notice_message("config_validate::process_terminated", e.to_string());
Ok(())
}
}
@@ -76,19 +76,17 @@ pub async fn delete_profile(index: String) -> CmdResult {
/// 修改profiles的配置
#[tauri::command]
pub async fn patch_profiles_config(
profiles: IProfiles
) -> CmdResult<bool> {
pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
println!("[cmd配置patch] 开始修改配置文件");
// 保存当前配置,以便在验证失败时恢复
let current_profile = Config::profiles().latest().current.clone();
println!("[cmd配置patch] 当前配置: {:?}", current_profile);
// 更新profiles配置
println!("[cmd配置patch] 正在更新配置草稿");
wrap_err!({ Config::profiles().draft().patch_config(profiles) })?;
// 更新配置并进行验证
match CoreManager::global().update_config().await {
Ok((true, _)) => {
@@ -102,7 +100,7 @@ pub async fn patch_profiles_config(
Ok((false, error_msg)) => {
println!("[cmd配置patch] 配置验证失败: {}", error_msg);
Config::profiles().discard();
// 如果验证失败,恢复到之前的配置
if let Some(prev_profile) = current_profile {
println!("[cmd配置patch] 尝试恢复到之前的配置: {}", prev_profile);
@@ -124,7 +122,7 @@ pub async fn patch_profiles_config(
Err(e) => {
println!("[cmd配置patch] 更新过程发生错误: {}", e);
Config::profiles().discard();
handle::Handle::notice_message("config_validate::boot_error", &e.to_string());
handle::Handle::notice_message("config_validate::boot_error", e.to_string());
Ok(false)
}
}
@@ -134,9 +132,12 @@ pub async fn patch_profiles_config(
#[tauri::command]
pub async fn patch_profiles_config_by_profile_index(
_app_handle: tauri::AppHandle,
profile_index: String
profile_index: String,
) -> CmdResult<bool> {
let profiles = IProfiles{current: Some(profile_index), items: None};
let profiles = IProfiles {
current: Some(profile_index),
items: None,
};
patch_profiles_config(profiles).await
}

View File

@@ -1,11 +1,8 @@
use crate::{
config::*,
wrap_err,
};
use super::CmdResult;
use crate::{config::*, wrap_err};
use anyhow::Context;
use std::collections::HashMap;
use serde_yaml::Mapping;
use std::collections::HashMap;
/// 获取运行时配置
#[tauri::command]

View File

@@ -1,10 +1,5 @@
use crate::{
config::*,
core::*,
utils::dirs,
wrap_err,
};
use super::CmdResult;
use crate::{config::*, core::*, utils::dirs, wrap_err};
use std::fs;
/// 保存profiles的配置
@@ -20,7 +15,7 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
let profiles_guard = profiles.latest();
let item = wrap_err!(profiles_guard.get_item(&index))?;
// 确定是否为merge类型文件
let is_merge = item.itype.as_ref().map_or(false, |t| t == "merge");
let is_merge = item.itype.as_ref().is_some_and(|t| t == "merge");
let content = wrap_err!(item.read_file())?;
let path = item.file.clone().ok_or("file field is null")?;
let profiles_dir = wrap_err!(dirs::app_profiles_dir())?;
@@ -29,14 +24,20 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
// 保存新的配置文件
wrap_err!(fs::write(&file_path, file_data.clone().unwrap()))?;
let file_path_str = file_path.to_string_lossy().to_string();
println!("[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}", file_path_str, is_merge_file);
println!(
"[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}",
file_path_str, is_merge_file
);
// 对于 merge 文件,只进行语法验证,不进行后续内核验证
if is_merge_file {
println!("[cmd配置save] 检测到merge文件只进行语法验证");
match CoreManager::global().validate_config_file(&file_path_str, Some(true)).await {
match CoreManager::global()
.validate_config_file(&file_path_str, Some(true))
.await
{
Ok((true, _)) => {
println!("[cmd配置save] merge文件语法验证通过");
// 成功后尝试更新整体配置
@@ -63,9 +64,12 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
}
}
}
// 非merge文件使用完整验证流程
match CoreManager::global().validate_config_file(&file_path_str, None).await {
match CoreManager::global()
.validate_config_file(&file_path_str, None)
.await
{
Ok((true, _)) => {
println!("[cmd配置save] 验证成功");
Ok(())
@@ -74,16 +78,17 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
println!("[cmd配置save] 验证失败: {}", error_msg);
// 恢复原始配置文件
wrap_err!(fs::write(&file_path, original_content))?;
// 智能判断错误类型
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) {
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通知处理
println!("[cmd配置save] YAML配置文件验证失败发送通知");
let result = (false, error_msg.clone());
@@ -98,7 +103,7 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
println!("[cmd配置save] 其他类型验证失败,发送一般通知");
handle::Handle::notice_message("config_validate::error", &error_msg);
}
Ok(())
}
Err(e) => {

View File

@@ -1,8 +1,10 @@
use super::CmdResult;
use crate::core::handle;
use crate::module::sysinfo::PlatformSpecification;
use crate::{
core::{self, handle, service, CoreManager},
module::sysinfo::PlatformSpecification,
wrap_err,
};
use tauri_plugin_clipboard_manager::ClipboardExt;
use crate::{core::{self, CoreManager, service}, wrap_err};
#[tauri::command]
pub async fn export_diagnostic_info() -> CmdResult<()> {
@@ -11,8 +13,7 @@ pub async fn export_diagnostic_info() -> CmdResult<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let cliboard = app_handle.clipboard();
if let Err(_) = cliboard.write_text(info) {
if cliboard.write_text(info).is_err() {
log::error!(target: "app", "Failed to write to clipboard");
}
Ok(())

View File

@@ -4,8 +4,7 @@ use super::CmdResult;
#[cfg(windows)]
mod platform {
use super::CmdResult;
use crate::core::win_uwp;
use crate::wrap_err;
use crate::{core::win_uwp, wrap_err};
pub async fn invoke_uwp_tool() -> CmdResult {
wrap_err!(win_uwp::invoke_uwptools().await)

View File

@@ -1,5 +1,5 @@
use crate::core::*;
use super::CmdResult;
use crate::core::*;
/// 发送脚本验证通知消息
#[tauri::command]
@@ -13,7 +13,7 @@ pub async fn script_validate_notice(status: String, msg: String) -> CmdResult {
pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str) {
if !result.0 {
let error_msg = &result.1;
// 根据错误消息内容判断错误类型
let status = if error_msg.starts_with("File not found:") {
"config_validate::file_not_found"
@@ -27,7 +27,7 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
// 如果是其他类型错误,作为一般脚本错误处理
"config_validate::script_error"
};
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
handle::Handle::notice_message(status, error_msg);
}
@@ -37,12 +37,15 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
#[tauri::command]
pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
log::info!(target: "app", "验证脚本文件: {}", file_path);
match CoreManager::global().validate_config_file(&file_path, None).await {
match CoreManager::global()
.validate_config_file(&file_path, None)
.await
{
Ok(result) => {
handle_script_validation_notice(&result, "脚本文件");
Ok(result.0) // 返回验证结果布尔值
},
Ok(result.0) // 返回验证结果布尔值
}
Err(e) => {
let error_msg = e.to_string();
log::error!(target: "app", "验证脚本文件过程发生错误: {}", error_msg);
@@ -58,10 +61,10 @@ pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
if !result.0 {
let error_msg = &result.1;
println!("[通知] 处理{}验证错误: {}", file_type, error_msg);
// 检查是否为merge文件
let is_merge_file = file_type.contains("合并");
// 根据错误消息内容判断错误类型
let status = if error_msg.starts_with("File not found:") {
"config_validate::file_not_found"
@@ -93,7 +96,7 @@ pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
"config_validate::yaml_error"
}
};
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
println!("[通知] 发送通知: status={}, msg={}", status, error_msg);
handle::Handle::notice_message(status, error_msg);

View File

@@ -1,9 +1,5 @@
use crate::{
config::*,
feat,
wrap_err,
};
use super::CmdResult;
use crate::{config::*, feat, wrap_err};
/// 获取Verge配置
#[tauri::command]

View File

@@ -1,10 +1,5 @@
use crate::{
core,
config::*,
feat,
wrap_err,
};
use super::CmdResult;
use crate::{config::*, core, feat, wrap_err};
use reqwest_dav::list_cmd::ListFile;
/// 保存 WebDAV 配置