Merge branch 'dev' into chore/i18n

This commit is contained in:
Slinetrac
2025-11-06 11:56:47 +08:00
Unverified
23 changed files with 93 additions and 94 deletions

View File

@@ -234,4 +234,15 @@ suspicious_operation_groupings = "deny"
string_lit_as_bytes = "deny"
significant_drop_tightening = "deny"
significant_drop_in_scrutinee = "deny"
redundant_clone = "deny"
redundant_clone = "deny"
# option_if_let_else = "deny" // 过于激进,暂时不开启
needless_pass_by_ref_mut = "deny"
needless_collect = "deny"
missing_const_for_fn = "deny"
iter_with_drain = "deny"
iter_on_single_items = "deny"
iter_on_empty_collections = "deny"
# fallible_impl_from = "deny" // 过于激进,暂时不开启
equatable_if_let = "deny"
collection_is_never_read = "deny"
branches_sharing_code = "deny"

View File

@@ -189,7 +189,6 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
})?;
logging!(info, Type::Config, "DNS config successfully applied");
handle::Handle::refresh_clash();
} else {
// 当关闭DNS设置时重新生成配置不加载DNS配置文件
logging!(
@@ -212,9 +211,9 @@ pub async fn apply_dns_config(apply: bool) -> CmdResult {
})?;
logging!(info, Type::Config, "Config regenerated successfully");
handle::Handle::refresh_clash();
}
handle::Handle::refresh_clash();
Ok(())
}

View File

@@ -13,19 +13,23 @@ pub(super) async fn check_youtube_premium(client: &Client) -> UnlockItem {
Ok(response) => {
if let Ok(body) = response.text().await {
let body_lower = body.to_lowercase();
let mut status = "Failed";
let mut region = None;
if body_lower.contains("youtube premium is not available in your country") {
return UnlockItem {
name: "Youtube Premium".to_string(),
status: "No".to_string(),
region: None,
check_time: Some(get_local_date_string()),
};
}
if body_lower.contains("ad-free") {
let re = match Regex::new(r#"id="country-code"[^>]*>([^<]+)<"#) {
Ok(re) => re,
status = "No";
} else if body_lower.contains("ad-free") {
match Regex::new(r#"id="country-code"[^>]*>([^<]+)<"#) {
Ok(re) => {
if let Some(caps) = re.captures(&body)
&& let Some(m) = caps.get(1)
{
let country_code = m.as_str().trim();
let emoji = country_code_to_emoji(country_code);
region = Some(format!("{emoji}{country_code}"));
status = "Yes";
}
}
Err(e) => {
logging!(
error,
@@ -33,34 +37,14 @@ pub(super) async fn check_youtube_premium(client: &Client) -> UnlockItem {
"Failed to compile YouTube Premium regex: {}",
e
);
return UnlockItem {
name: "Youtube Premium".to_string(),
status: "Failed".to_string(),
region: None,
check_time: Some(get_local_date_string()),
};
}
};
let region = re.captures(&body).and_then(|caps| {
caps.get(1).map(|m| {
let country_code = m.as_str().trim();
let emoji = country_code_to_emoji(country_code);
format!("{emoji}{country_code}")
})
});
return UnlockItem {
name: "Youtube Premium".to_string(),
status: "Yes".to_string(),
region,
check_time: Some(get_local_date_string()),
};
}
}
UnlockItem {
name: "Youtube Premium".to_string(),
status: "Failed".to_string(),
region: None,
status: status.to_string(),
region,
check_time: Some(get_local_date_string()),
}
} else {

View File

@@ -17,7 +17,7 @@ mod platform {
mod platform {
use super::CmdResult;
pub fn invoke_uwp_tool() -> CmdResult {
pub const fn invoke_uwp_tool() -> CmdResult {
Ok(())
}
}

View File

@@ -611,6 +611,6 @@ impl PrfItem {
}
// 向前兼容,默认为订阅启用自动更新
fn default_allow_auto_update() -> Option<bool> {
const fn default_allow_auto_update() -> Option<bool> {
Some(true)
}

View File

@@ -102,12 +102,12 @@ impl IProfiles {
}
}
pub fn get_current(&self) -> Option<&String> {
pub const fn get_current(&self) -> Option<&String> {
self.current.as_ref()
}
/// get items ref
pub fn get_items(&self) -> Option<&Vec<PrfItem>> {
pub const fn get_items(&self) -> Option<&Vec<PrfItem>> {
self.items.as_ref()
}

View File

@@ -531,7 +531,7 @@ impl IVerge {
patch!(enable_external_controller);
}
pub fn get_singleton_port() -> u16 {
pub const fn get_singleton_port() -> u16 {
crate::constants::network::ports::SINGLETON_SERVER
}

View File

@@ -347,11 +347,12 @@ impl AsyncProxyQuery {
&mut buffer_size,
);
let mut proxy_server = String::new();
if server_result == 0 && value_type == REG_SZ && buffer_size > 0 {
let proxy_server = if server_result == 0 && value_type == REG_SZ && buffer_size > 0 {
let end_pos = buffer.iter().position(|&x| x == 0).unwrap_or(buffer.len());
proxy_server = String::from_utf16_lossy(&buffer[..end_pos]);
}
String::from_utf16_lossy(&buffer[..end_pos])
} else {
String::new()
};
// 读取代理绕过列表
let proxy_override_name = "ProxyOverride\0".encode_utf16().collect::<Vec<u16>>();
@@ -368,14 +369,16 @@ impl AsyncProxyQuery {
&mut bypass_buffer_size,
);
let mut bypass_list = String::new();
if override_result == 0 && bypass_value_type == REG_SZ && bypass_buffer_size > 0 {
let end_pos = bypass_buffer
.iter()
.position(|&x| x == 0)
.unwrap_or(bypass_buffer.len());
bypass_list = String::from_utf16_lossy(&bypass_buffer[..end_pos]);
}
let bypass_list =
if override_result == 0 && bypass_value_type == REG_SZ && bypass_buffer_size > 0 {
let end_pos = bypass_buffer
.iter()
.position(|&x| x == 0)
.unwrap_or(bypass_buffer.len());
String::from_utf16_lossy(&bypass_buffer[..end_pos])
} else {
String::new()
};
RegCloseKey(hkey);

View File

@@ -45,7 +45,7 @@ enum Operation {
}
impl Operation {
fn timeout(&self) -> u64 {
const fn timeout(&self) -> u64 {
match self {
Self::Upload => TIMEOUT_UPLOAD,
Self::Download => TIMEOUT_DOWNLOAD,

View File

@@ -84,7 +84,7 @@ impl fmt::Display for SystemHotkey {
#[cfg(target_os = "macos")]
impl SystemHotkey {
pub fn function(self) -> HotkeyFunction {
pub const fn function(self) -> HotkeyFunction {
match self {
Self::CmdQ => HotkeyFunction::Quit,
Self::CmdW => HotkeyFunction::Hide,

View File

@@ -137,7 +137,7 @@ impl CoreManager {
}
}
fn is_connection_io_error(kind: std::io::ErrorKind) -> bool {
const fn is_connection_io_error(kind: std::io::ErrorKind) -> bool {
matches!(
kind,
std::io::ErrorKind::ConnectionAborted

View File

@@ -136,7 +136,7 @@ async fn uninstall_service() -> Result<()> {
let elevator = crate::utils::help::linux_elevator();
let status = match get_effective_uid() {
0 => StdCommand::new(uninstall_shell).status()?,
_ => StdCommand::new(elevator.clone())
_ => StdCommand::new(elevator)
.arg("sh")
.arg("-c")
.arg(uninstall_shell)
@@ -177,7 +177,7 @@ async fn install_service() -> Result<()> {
let elevator = crate::utils::help::linux_elevator();
let status = match get_effective_uid() {
0 => StdCommand::new(install_shell).status()?,
_ => StdCommand::new(elevator.clone())
_ => StdCommand::new(elevator)
.arg("sh")
.arg("-c")
.arg(install_shell)
@@ -449,7 +449,7 @@ impl ServiceManager {
Self(ServiceStatus::Unavailable("Need Checks".into()))
}
pub fn config() -> Option<clash_verge_service_ipc::IpcConfig> {
pub const fn config() -> Option<clash_verge_service_ipc::IpcConfig> {
Some(clash_verge_service_ipc::IpcConfig {
default_timeout: Duration::from_millis(30),
retry_delay: Duration::from_millis(250),

View File

@@ -252,8 +252,8 @@ impl Timer {
// Now perform async operations without holding locks
for (uid, tid, interval) in operations_to_add {
// Re-acquire locks for individual operations
let mut delay_timer = self.delay_timer.write();
if let Err(e) = self.add_task(&mut delay_timer, uid.clone(), tid, interval) {
let delay_timer = self.delay_timer.write();
if let Err(e) = self.add_task(&delay_timer, uid.clone(), tid, interval) {
logging_error!(Type::Timer, "Failed to add task for uid {}: {}", uid, e);
// Rollback on failure - remove from timer_map
@@ -370,7 +370,7 @@ impl Timer {
/// Add a timer task with better error handling
fn add_task(
&self,
delay_timer: &mut DelayTimer,
delay_timer: &DelayTimer,
uid: String,
tid: TaskID,
minutes: u64,

View File

@@ -16,7 +16,7 @@ pub struct CoreConfigValidator {
}
impl CoreConfigValidator {
pub fn new() -> Self {
pub const fn new() -> Self {
Self {
is_processing: AtomicBool::new(false),
}

View File

@@ -351,23 +351,21 @@ pub fn run() {
});
}
#[cfg(target_os = "macos")]
pub fn handle_window_destroyed() {
#[cfg(target_os = "macos")]
{
use crate::core::hotkey::SystemHotkey;
AsyncHandler::spawn(move || async move {
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdQ);
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdW);
let is_enable_global_hotkey = Config::verge()
.await
.latest_arc()
.enable_global_hotkey
.unwrap_or(true);
if !is_enable_global_hotkey {
let _ = hotkey::Hotkey::global().reset();
}
});
}
use crate::core::hotkey::SystemHotkey;
AsyncHandler::spawn(move || async move {
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdQ);
let _ = hotkey::Hotkey::global().unregister_system_hotkey(SystemHotkey::CmdW);
let is_enable_global_hotkey = Config::verge()
.await
.latest_arc()
.enable_global_hotkey
.unwrap_or(true);
if !is_enable_global_hotkey {
let _ = hotkey::Hotkey::global().reset();
}
});
}
}
@@ -447,6 +445,7 @@ pub fn run() {
tauri::WindowEvent::Focused(focused) => {
event_handlers::handle_window_focus(focused);
}
#[cfg(target_os = "macos")]
tauri::WindowEvent::Destroyed => {
event_handlers::handle_window_destroyed();
}

View File

@@ -4,8 +4,8 @@ fn main() {
console_subscriber::init();
// Check for --no-tray command line argument
let args: Vec<String> = std::env::args().collect();
if args.contains(&"--no-tray".into()) {
#[cfg(target_os = "linux")]
if std::env::args().any(|x| x == "--no-tray") {
unsafe {
std::env::set_var("CLASH_VERGE_DISABLE_TRAY", "1");
}

View File

@@ -36,7 +36,7 @@ impl From<u8> for LightweightState {
}
impl LightweightState {
fn as_u8(self) -> u8 {
const fn as_u8(self) -> u8 {
self as u8
}
}

View File

@@ -20,7 +20,7 @@ impl Drop for CommandChildGuard {
}
impl CommandChildGuard {
pub fn new(child: CommandChild) -> Self {
pub const fn new(child: CommandChild) -> Self {
Self(Some(child))
}

View File

@@ -6,6 +6,8 @@ use crate::{
use anyhow::Result;
use async_trait::async_trait;
use once_cell::sync::OnceCell;
#[cfg(unix)]
use std::iter;
use std::{fs, path::PathBuf};
use tauri::Manager;
@@ -226,8 +228,7 @@ pub fn get_encryption_key() -> Result<Vec<u8>> {
#[cfg(unix)]
pub fn ensure_mihomo_safe_dir() -> Option<PathBuf> {
["/tmp"]
.iter()
iter::once("/tmp")
.map(PathBuf::from)
.find(|path| path.exists())
.or_else(|| {

View File

@@ -506,7 +506,7 @@ pub fn init_scheme() -> Result<()> {
Ok(())
}
#[cfg(target_os = "macos")]
pub fn init_scheme() -> Result<()> {
pub const fn init_scheme() -> Result<()> {
Ok(())
}

View File

@@ -19,7 +19,7 @@ struct IntelGpuDetection {
}
impl IntelGpuDetection {
fn should_disable_dmabuf(&self) -> bool {
const fn should_disable_dmabuf(&self) -> bool {
self.intel_is_primary || self.inconclusive
}
}
@@ -41,7 +41,7 @@ enum NvidiaDmabufDisableReason {
}
impl NvidiaGpuDetection {
fn disable_reason(&self, session: &SessionEnv) -> Option<NvidiaDmabufDisableReason> {
const fn disable_reason(&self, session: &SessionEnv) -> Option<NvidiaDmabufDisableReason> {
if !session.is_wayland {
return None;
}
@@ -144,11 +144,11 @@ impl DmabufOverrides {
}
}
fn has_env_override(&self) -> bool {
const fn has_env_override(&self) -> bool {
self.dmabuf_override.is_some()
}
fn should_override_env(&self, decision: &DmabufDecision) -> bool {
const fn should_override_env(&self, decision: &DmabufDecision) -> bool {
if self.user_preference.is_some() {
return true;
}

View File

@@ -26,7 +26,7 @@ pub struct HttpResponse {
}
impl HttpResponse {
pub fn new(status: StatusCode, headers: HeaderMap, body: String) -> Self {
pub const fn new(status: StatusCode, headers: HeaderMap, body: String) -> Self {
Self {
status,
headers,
@@ -34,11 +34,11 @@ impl HttpResponse {
}
}
pub fn status(&self) -> StatusCode {
pub const fn status(&self) -> StatusCode {
self.status
}
pub fn headers(&self) -> &HeaderMap {
pub const fn headers(&self) -> &HeaderMap {
&self.headers
}

View File

@@ -31,6 +31,8 @@ pub async fn check_singleton() -> Result<()> {
let client = ClientBuilder::new()
.timeout(Duration::from_millis(500))
.build()?;
// 需要确保 Send
#[allow(clippy::needless_collect)]
let argvs: Vec<std::string::String> = std::env::args().collect();
if argvs.len() > 1 {
#[cfg(not(target_os = "macos"))]