From 4ed36f622308df9e19bb4b7d70c7d944958dd9a5 Mon Sep 17 00:00:00 2001 From: Tunglies Date: Wed, 5 Mar 2025 00:45:08 +0800 Subject: [PATCH] refacture: Mihomo API integration (#2900) * feat: add mihomo_api crate as a workspace member Added a new mihomo_api crate to handle interactions with the Mihomo API. This modular approach provides a dedicated interface for fetching and managing proxy data from Mihomo servers. The implementation includes functionality to refresh and retrieve both proxies and provider proxies with proper error handling and timeouts. Added this crate as a workspace member and included it as a dependency in the main project. * Refactors Mihomo API integration Simplifies proxy fetching by removing the MihomoManager structure. Updates the get_proxies and get_providers_proxies functions to directly use the mihomo_api module. Removes unused Mihomo API related files and modules for cleaner codebase. Enhances overall maintainability and performance. --- src-tauri/Cargo.lock | 27 ++- src-tauri/Cargo.toml | 6 + src-tauri/src/cmd/proxy.rs | 45 ++--- src-tauri/src/config/api/mihomo.rs | 1 - src-tauri/src/config/api/mod.rs | 1 - src-tauri/src/config/mod.rs | 3 - src-tauri/src/core/clash_api.rs | 2 +- src-tauri/src/crate_mihomo_api/Cargo.toml | 14 ++ src-tauri/src/crate_mihomo_api/src/lib.rs | 76 +++++++++ src-tauri/src/crate_mihomo_api/src/model.rs | 27 +++ .../crate_mihomo_api/tests/test_mihomo_api.rs | 28 ++++ src-tauri/src/lib.rs | 1 - src-tauri/src/model/api/common.rs | 20 --- src-tauri/src/model/api/mihomo.rs | 5 - src-tauri/src/model/api/mod.rs | 2 - src-tauri/src/model/mod.rs | 1 - src-tauri/src/module/api/common.rs | 70 -------- src-tauri/src/module/api/mihomo.rs | 108 ------------ src-tauri/src/module/api/mod.rs | 2 - src-tauri/src/module/mihomo.rs | 158 ------------------ src-tauri/src/module/mod.rs | 4 +- 21 files changed, 190 insertions(+), 411 deletions(-) delete mode 100644 src-tauri/src/config/api/mihomo.rs delete mode 100644 src-tauri/src/config/api/mod.rs create mode 100644 src-tauri/src/crate_mihomo_api/Cargo.toml create mode 100644 src-tauri/src/crate_mihomo_api/src/lib.rs create mode 100644 src-tauri/src/crate_mihomo_api/src/model.rs create mode 100644 src-tauri/src/crate_mihomo_api/tests/test_mihomo_api.rs delete mode 100644 src-tauri/src/model/api/common.rs delete mode 100644 src-tauri/src/model/api/mihomo.rs delete mode 100644 src-tauri/src/model/api/mod.rs delete mode 100644 src-tauri/src/model/mod.rs delete mode 100644 src-tauri/src/module/api/common.rs delete mode 100644 src-tauri/src/module/api/mihomo.rs delete mode 100644 src-tauri/src/module/api/mod.rs delete mode 100644 src-tauri/src/module/mihomo.rs diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c3e605b8..5830c57d 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1078,6 +1078,7 @@ dependencies = [ "imageproc", "log", "log4rs", + "mihomo_api", "mockito", "nanoid", "network-interface", @@ -3723,9 +3724,9 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" [[package]] name = "log" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" dependencies = [ "serde", ] @@ -3896,6 +3897,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mihomo_api" +version = "0.0.0" +dependencies = [ + "reqwest", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "mime" version = "0.3.17" @@ -5996,9 +6007,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] @@ -6038,9 +6049,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", @@ -6060,9 +6071,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa 1.0.14", "memchr", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 24808a49..cb71a46f 100755 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -68,6 +68,7 @@ tokio-tungstenite = "0.26.1" futures = "0.3" sys-locale = "0.3.1" async-trait = "0.1.86" +mihomo_api = { path = "./src/crate_mihomo_api" } [target.'cfg(windows)'.dependencies] runas = "=1.2.0" @@ -126,3 +127,8 @@ crate-type = ["staticlib", "cdylib", "rlib"] env_logger = "0.11.0" mockito = "1.2.0" tempfile = "3.17.1" + +[workspace] +members = [ + "src/crate_mihomo_api" +] diff --git a/src-tauri/src/cmd/proxy.rs b/src-tauri/src/cmd/proxy.rs index e2ddf771..3e0f0823 100644 --- a/src-tauri/src/cmd/proxy.rs +++ b/src-tauri/src/cmd/proxy.rs @@ -1,35 +1,26 @@ use super::CmdResult; -use crate::module::mihomo::MihomoManager; -use tauri::async_runtime; +use crate::core; +use mihomo_api; + #[tauri::command] pub async fn get_proxies() -> CmdResult { - let proxies = async_runtime::spawn_blocking(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - let manager = MihomoManager::new(); - { - let mut write_guard = manager.write(); - rt.block_on(write_guard.refresh_proxies()); - } - let read_guard = manager.read(); - read_guard.fetch_proxies().clone() - }) - .await.map_err(|e| e.to_string())?; - Ok(proxies) + let (mihomo_server, _) = core::clash_api::clash_client_info().unwrap(); + let mihomo = mihomo_api::MihomoManager::new(mihomo_server); + Ok(mihomo + .refresh_proxies() + .await + .unwrap() + .get_proxies()) } #[tauri::command] pub async fn get_providers_proxies() -> CmdResult { - let providers_proxies = async_runtime::spawn_blocking(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - let manager = MihomoManager::new(); - { - let mut write_guard = manager.write(); - rt.block_on(write_guard.refresh_providers_proxies()); - } - let read_guard = manager.read(); - read_guard.fetch_providers_proxies().clone() - }) - .await.map_err(|e| e.to_string())?; - Ok(providers_proxies) -} \ No newline at end of file + let (mihomo_server, _) = core::clash_api::clash_client_info().unwrap(); + let mihomo = mihomo_api::MihomoManager::new(mihomo_server); + Ok(mihomo + .refresh_providers_proxies() + .await + .unwrap() + .get_providers_proxies()) +} diff --git a/src-tauri/src/config/api/mihomo.rs b/src-tauri/src/config/api/mihomo.rs deleted file mode 100644 index 46873b96..00000000 --- a/src-tauri/src/config/api/mihomo.rs +++ /dev/null @@ -1 +0,0 @@ -pub const MIHOMO_URL: &str = concat!("http://", "127.0.0.1", ":", "9097"); diff --git a/src-tauri/src/config/api/mod.rs b/src-tauri/src/config/api/mod.rs deleted file mode 100644 index 0f3c8057..00000000 --- a/src-tauri/src/config/api/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod mihomo; diff --git a/src-tauri/src/config/mod.rs b/src-tauri/src/config/mod.rs index a3ddace0..69b1b123 100644 --- a/src-tauri/src/config/mod.rs +++ b/src-tauri/src/config/mod.rs @@ -21,6 +21,3 @@ pub const DEFAULT_PAC: &str = r#"function FindProxyForURL(url, host) { return "PROXY 127.0.0.1:%mixed-port%; SOCKS5 127.0.0.1:%mixed-port%; DIRECT;"; } "#; - - -pub mod api; \ No newline at end of file diff --git a/src-tauri/src/core/clash_api.rs b/src-tauri/src/core/clash_api.rs index 60af1204..d6115b4e 100644 --- a/src-tauri/src/core/clash_api.rs +++ b/src-tauri/src/core/clash_api.rs @@ -76,7 +76,7 @@ pub async fn get_proxy_delay( } /// 根据clash info获取clash服务地址和请求头 -fn clash_client_info() -> Result<(String, HeaderMap)> { +pub fn clash_client_info() -> Result<(String, HeaderMap)> { let client = { Config::clash().data().get_client_info() }; let server = format!("http://{}", client.server); diff --git a/src-tauri/src/crate_mihomo_api/Cargo.toml b/src-tauri/src/crate_mihomo_api/Cargo.toml new file mode 100644 index 00000000..1a3ac3bf --- /dev/null +++ b/src-tauri/src/crate_mihomo_api/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "mihomo_api" +edition = "2024" + +[features] +debug = [] + +[dependencies] +reqwest = { version = "0.12.12", features = ["json"] } +serde = { version = "1.0.218", features = ["derive"] } +serde_json = "1.0.140" + +[dev-dependencies] +tokio = { version = "1.43.0", features = ["rt", "macros"] } \ No newline at end of file diff --git a/src-tauri/src/crate_mihomo_api/src/lib.rs b/src-tauri/src/crate_mihomo_api/src/lib.rs new file mode 100644 index 00000000..0b503650 --- /dev/null +++ b/src-tauri/src/crate_mihomo_api/src/lib.rs @@ -0,0 +1,76 @@ +use std::{ + sync::{Arc, Mutex}, + time::Duration, +}; +pub mod model; +pub use model::{MihomoData, MihomoManager}; + +impl MihomoManager { + pub fn new(mihomo_server: String) -> Self { + Self { + mihomo_server, + data: Arc::new(Mutex::new(MihomoData { + proxies: serde_json::Value::Null, + providers_proxies: serde_json::Value::Null, + })), + } + } + + fn update_proxies(&self, proxies: serde_json::Value) { + let mut data = self.data.lock().unwrap(); + data.proxies = proxies; + } + + fn update_providers_proxies(&self, providers_proxies: serde_json::Value) { + let mut data = self.data.lock().unwrap(); + data.providers_proxies = providers_proxies; + } + + pub fn get_proxies(&self) -> serde_json::Value { + let data = self.data.lock().unwrap(); + data.proxies.clone() + } + + pub fn get_providers_proxies(&self) -> serde_json::Value { + let data = self.data.lock().unwrap(); + data.providers_proxies.clone() + } + + pub async fn refresh_proxies(&self) -> Result<&Self, String> { + let url = format!("{}/proxies", self.mihomo_server); + let response = reqwest::ClientBuilder::new() + .no_proxy() + .timeout(Duration::from_secs(3)) + .build() + .map_err(|e| e.to_string())? + .get(url) + .send() + .await + .map_err(|e| e.to_string())? + .json::() + .await + .map_err(|e| e.to_string())?; + let proxies = response; + self.update_proxies(proxies); + Ok(self) + } + + pub async fn refresh_providers_proxies(&self) -> Result<&Self, String> { + let url = format!("{}/providers/proxies", self.mihomo_server); + let response = reqwest::ClientBuilder::new() + .no_proxy() + .timeout(Duration::from_secs(3)) + .build() + .map_err(|e| e.to_string())? + .get(url) + .send() + .await + .map_err(|e| e.to_string())? + .json::() + .await + .map_err(|e| e.to_string())?; + let proxies = response; + self.update_providers_proxies(proxies); + Ok(self) + } +} diff --git a/src-tauri/src/crate_mihomo_api/src/model.rs b/src-tauri/src/crate_mihomo_api/src/model.rs new file mode 100644 index 00000000..4af4b1be --- /dev/null +++ b/src-tauri/src/crate_mihomo_api/src/model.rs @@ -0,0 +1,27 @@ +use std::sync::{Arc, Mutex}; + +pub struct MihomoData { + pub(crate) proxies: serde_json::Value, + pub(crate) providers_proxies: serde_json::Value, +} + +#[derive(Clone)] +pub struct MihomoManager { + pub(crate) mihomo_server: String, + pub(crate) data: Arc>, +} + +#[cfg(feature = "debug")] +impl Drop for MihomoData { + fn drop(&mut self) { + println!("Dropping MihomoData"); + } +} + +#[cfg(feature = "debug")] +impl Drop for MihomoManager { + fn drop(&mut self) { + println!("Dropping MihomoManager"); + } + +} \ No newline at end of file diff --git a/src-tauri/src/crate_mihomo_api/tests/test_mihomo_api.rs b/src-tauri/src/crate_mihomo_api/tests/test_mihomo_api.rs new file mode 100644 index 00000000..681c6b10 --- /dev/null +++ b/src-tauri/src/crate_mihomo_api/tests/test_mihomo_api.rs @@ -0,0 +1,28 @@ +use mihomo_api; + +#[test] +fn test_mihomo_manager_init() { + let manager = mihomo_api::MihomoManager::new("url".into()); + assert_eq!(manager.get_proxies(), serde_json::Value::Null); + assert_eq!(manager.get_providers_proxies(), serde_json::Value::Null); +} + +#[tokio::test] +async fn test_refresh_proxies() { + let manager = mihomo_api::MihomoManager::new("http://127.0.0.1:9097".into()); + let manager = manager.refresh_proxies().await.unwrap(); + let proxies = manager.get_proxies(); + let providers = manager.get_providers_proxies(); + assert_ne!(proxies, serde_json::Value::Null); + assert_eq!(providers, serde_json::Value::Null); +} + +#[tokio::test] +async fn test_refresh_providers_proxies() { + let manager = mihomo_api::MihomoManager::new("http://127.0.0.1:9097".into()); + let manager = manager.refresh_providers_proxies().await.unwrap(); + let proxies = manager.get_proxies(); + let providers = manager.get_providers_proxies(); + assert_eq!(proxies, serde_json::Value::Null); + assert_ne!(providers, serde_json::Value::Null); +} \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ccfddebe..b8a9ee33 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -4,7 +4,6 @@ mod core; mod enhance; mod feat; mod utils; -mod model; mod module; use crate::core::hotkey; use crate::utils::{resolve, resolve::resolve_scheme, server}; diff --git a/src-tauri/src/model/api/common.rs b/src-tauri/src/model/api/common.rs deleted file mode 100644 index cd83945c..00000000 --- a/src-tauri/src/model/api/common.rs +++ /dev/null @@ -1,20 +0,0 @@ -use reqwest::Client; - -#[allow(unused)] -pub(crate) struct ApiCaller<'a> { - pub(crate) url: &'a str, - pub(crate) client: Client, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_api_caller() { - let _api_caller = ApiCaller { - url: "https://example.com", - client: Client::new(), - }; - } -} diff --git a/src-tauri/src/model/api/mihomo.rs b/src-tauri/src/model/api/mihomo.rs deleted file mode 100644 index ad14be62..00000000 --- a/src-tauri/src/model/api/mihomo.rs +++ /dev/null @@ -1,5 +0,0 @@ -use super::common::ApiCaller; - -pub struct MihomoAPICaller { - pub(crate) caller: ApiCaller<'static>, -} diff --git a/src-tauri/src/model/api/mod.rs b/src-tauri/src/model/api/mod.rs deleted file mode 100644 index bee8fa98..00000000 --- a/src-tauri/src/model/api/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod common; -pub mod mihomo; diff --git a/src-tauri/src/model/mod.rs b/src-tauri/src/model/mod.rs deleted file mode 100644 index c78317c1..00000000 --- a/src-tauri/src/model/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod api; \ No newline at end of file diff --git a/src-tauri/src/module/api/common.rs b/src-tauri/src/module/api/common.rs deleted file mode 100644 index dab4cc69..00000000 --- a/src-tauri/src/module/api/common.rs +++ /dev/null @@ -1,70 +0,0 @@ -use crate::model::api::common::ApiCaller; -use async_trait::async_trait; -use reqwest::{ - header::{HeaderMap, HeaderName, HeaderValue}, - RequestBuilder, -}; -use serde::de::DeserializeOwned; - -impl<'a> ApiCaller<'a> { - pub async fn send_request( - &self, - method: &str, - path: &str, - body: Option<&str>, - headers: Option>, - ) -> Result { - let full_url = format!("{}{}", self.url, path); // 拼接完整 URL - let mut request: RequestBuilder = match method { - "GET" => self.client.get(&full_url), - "POST" => self - .client - .post(&full_url) - .body(body.unwrap_or("").to_string()), - "PUT" => self - .client - .put(&full_url) - .body(body.unwrap_or("").to_string()), - "DELETE" => self.client.delete(&full_url), - _ => return Err("Unsupported HTTP method".to_string()), - }; - - // 处理 headers - if let Some(hdrs) = headers { - let mut header_map = HeaderMap::new(); - for (key, value) in hdrs { - if let (Ok(header_name), Ok(header_value)) = ( - HeaderName::from_bytes(key.as_bytes()), - HeaderValue::from_str(value), - ) { - header_map.insert(header_name, header_value); - } - } - request = request.headers(header_map); - } - - let response = request.send().await.map_err(|e| e.to_string())?; - response.text().await.map_err(|e| e.to_string()) - } -} - -#[allow(unused)] -#[async_trait] -pub trait ApiCallerTrait: Send + Sync { - async fn call_api( - &self, - method: &str, - path: &str, - body: Option<&str>, - headers: Option> - ) -> Result - where - T: DeserializeOwned + Send + Sync; - - fn parse_json_response(json_str: &str) -> Result - where - T: DeserializeOwned, - { - serde_json::from_str(json_str).map_err(|e| e.to_string()) - } -} diff --git a/src-tauri/src/module/api/mihomo.rs b/src-tauri/src/module/api/mihomo.rs deleted file mode 100644 index 09b6d0fa..00000000 --- a/src-tauri/src/module/api/mihomo.rs +++ /dev/null @@ -1,108 +0,0 @@ -use super::common::ApiCallerTrait; -use crate::config::api::mihomo::MIHOMO_URL; -use crate::model::api::common::ApiCaller; -use crate::model::api::mihomo::MihomoAPICaller; - -use async_trait::async_trait; -use once_cell::sync::OnceCell; -use parking_lot::RwLock; -use reqwest::Client; -use serde::de::DeserializeOwned; -use std::sync::Arc; - -impl MihomoAPICaller { - #[allow(dead_code)] - pub fn new() -> Arc> { - static INSTANCE: OnceCell>> = OnceCell::new(); - INSTANCE - .get_or_init(|| { - let client = Client::new(); - Arc::new(RwLock::new(MihomoAPICaller { - caller: ApiCaller { - url: MIHOMO_URL, - client, - }, - })) - }) - .clone() - } -} - -#[async_trait] -impl ApiCallerTrait for MihomoAPICaller { - async fn call_api( - &self, - method: &str, - path: &str, - body: Option<&str>, - headers: Option>, - ) -> Result - where - T: DeserializeOwned + Send + Sync, - { - let response = self - .caller - .send_request(method, path, body, headers) - .await - .map_err(|e| e.to_string())?; - Self::parse_json_response::(&response) - } -} - -#[allow(unused)] -impl MihomoAPICaller { - pub async fn get_proxies() -> Result { - Self::new() - .read() - .call_api("GET", "/proxies", None, None) - .await - } - - pub async fn get_providers_proxies() -> Result { - Self::new() - .read() - .call_api("GET", "/providers/proxies", None, None) - .await - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[tokio::test] - async fn test_mihomo_api_singleton() { - let mihomo_api_caller1 = MihomoAPICaller::new(); - let mihomo_api_caller2 = MihomoAPICaller::new(); - assert!(Arc::ptr_eq(&mihomo_api_caller1, &mihomo_api_caller2)); - } - - #[tokio::test] - async fn test_mihomo_api_version() { - let mihomo_caller = MihomoAPICaller::new(); - let response: Result = mihomo_caller - .read() - .call_api("GET", "/version", None, None) - .await; - assert!(response.is_ok()); - } - - #[tokio::test] - async fn test_mihomo_get_proxies() { - let response = MihomoAPICaller::get_proxies().await; - assert!(response.is_ok()); - if let Ok(proxies) = &response { - assert!(!proxies.get("proxies").is_none()); - } - } - - #[tokio::test] - async fn test_mihomo_get_providers_proxies() { - let response = MihomoAPICaller::get_providers_proxies().await; - println!("{:?}", response); - assert!(response.is_ok()); - if let Ok(providers_proxies) = &response { - assert!(!providers_proxies.get("providers").is_none()); - } - } -} diff --git a/src-tauri/src/module/api/mod.rs b/src-tauri/src/module/api/mod.rs deleted file mode 100644 index bee8fa98..00000000 --- a/src-tauri/src/module/api/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod common; -pub mod mihomo; diff --git a/src-tauri/src/module/mihomo.rs b/src-tauri/src/module/mihomo.rs deleted file mode 100644 index c1201d91..00000000 --- a/src-tauri/src/module/mihomo.rs +++ /dev/null @@ -1,158 +0,0 @@ -use crate::model::api::mihomo::MihomoAPICaller; -use once_cell::sync::OnceCell; -use parking_lot::RwLock; -use std::sync::Arc; - -#[allow(unused)] -pub struct MihomoManager { - proxies: serde_json::Value, - providers_proxies: serde_json::Value, -} - -#[allow(unused)] -impl MihomoManager { - pub fn new() -> Arc> { - static INSTANCE: OnceCell>> = OnceCell::new(); - INSTANCE - .get_or_init(|| { - Arc::new(RwLock::new(MihomoManager { - proxies: serde_json::Value::Null, - providers_proxies: serde_json::Value::Null, - })) - }) - .clone() - } - - pub fn fetch_proxies(&self) -> &serde_json::Value { - &self.proxies - } - - pub fn fetch_providers_proxies(&self) -> &serde_json::Value { - &self.providers_proxies - } - - pub async fn refresh_proxies(&mut self) { - match MihomoAPICaller::get_proxies().await { - Ok(proxies) => { - self.proxies = proxies; - } - Err(e) => { - log::error!("Failed to get proxies: {}", e); - } - } - } - - pub async fn refresh_providers_proxies(&mut self) { - match MihomoAPICaller::get_providers_proxies().await { - Ok(providers_proxies) => { - self.providers_proxies = providers_proxies; - }, - Err(e) => { - log::error!("Failed to get providers proxies: {}", e); - }, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - #[tokio::test] - async fn test_mihomo_manager_singleton() { - let manager1 = MihomoManager::new(); - let manager2 = MihomoManager::new(); - - assert!( - Arc::ptr_eq(&manager1, &manager2), - "Should return same instance" - ); - - let manager = manager1.read(); - assert!(manager.proxies.is_null()); - assert!(manager.providers_proxies.is_null()); - } - - #[tokio::test] - async fn test_refresh_proxies() { - let manager = MihomoManager::new(); - - // Test initial state - { - let data = manager.read(); - assert!(data.proxies.is_null()); - } - - // Test refresh - { - let mut data = manager.write(); - data.refresh_proxies().await; - // Note: Since this depends on external API call, - // we can only verify that the refresh call completes - // without panicking. For more thorough testing, - // we would need to mock the API caller. - } - } - - #[tokio::test] - async fn test_refresh_providers_proxies() { - let manager = MihomoManager::new(); - - // Test initial state - { - let data = manager.read(); - assert!(data.providers_proxies.is_null()); - } - - // Test refresh - { - let mut data = manager.write(); - data.refresh_providers_proxies().await; - // Note: Since this depends on external API call, - // we can only verify that the refresh call completes - // without panicking. For more thorough testing, - // we would need to mock the API caller. - } - } - - #[tokio::test] - async fn test_fetch_proxies() { - let manager = MihomoManager::new(); - - // Test initial state - { - let data = manager.read(); - let proxies = data.fetch_proxies(); - assert!(proxies.is_null()); - } - - // Test after refresh - { - let mut data = manager.write(); - data.refresh_proxies().await; - let _proxies = data.fetch_proxies(); - // Can only verify the method returns without panicking - // Would need API mocking for more thorough testing - } - } - - #[tokio::test] - async fn test_fetch_providers_proxies() { - let manager = MihomoManager::new(); - - // Test initial state - { - let data = manager.read(); - let providers_proxies = data.fetch_providers_proxies(); - assert!(providers_proxies.is_null()); - } - - // Test after refresh - { - let mut data = manager.write(); - data.refresh_providers_proxies().await; - let _providers_proxies = data.fetch_providers_proxies(); - // Can only verify the method returns without panicking - // Would need API mocking for more thorough testing - } - } -} diff --git a/src-tauri/src/module/mod.rs b/src-tauri/src/module/mod.rs index 0692611c..f146b310 100644 --- a/src-tauri/src/module/mod.rs +++ b/src-tauri/src/module/mod.rs @@ -1,3 +1 @@ -pub mod api; -pub mod sysinfo; -pub mod mihomo; \ No newline at end of file +pub mod sysinfo; \ No newline at end of file