diff --git a/Cargo.lock b/Cargo.lock index 93b824f52..f21aa35bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1144,6 +1144,7 @@ dependencies = [ "reqwest_dav", "runas", "rust-i18n", + "rust_iso3166", "scopeguard", "serde", "serde_json", @@ -1664,6 +1665,27 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "csv" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "csv-core" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +dependencies = [ + "memchr", +] + [[package]] name = "ctor" version = "0.2.9" @@ -1935,6 +1957,16 @@ dependencies = [ "dirs-sys 0.5.0", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + [[package]] name = "dirs-sys" version = "0.3.7" @@ -1958,6 +1990,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users 0.4.6", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -2131,6 +2174,12 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -3719,6 +3768,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi 0.5.2", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "is-wsl" version = "0.4.0" @@ -5561,6 +5621,20 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +dependencies = [ + "csv", + "encode_unicode", + "is-terminal", + "lazy_static", + "term", + "unicode-width", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -6303,6 +6377,18 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rust_iso3166" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0d3a0089ee08071ea1baaba83f2265c97f7646c53c3f92b205eb2cdaab72b1" +dependencies = [ + "js-sys", + "phf 0.11.3", + "prettytable-rs", + "wasm-bindgen", +] + [[package]] name = "rustc-hash" version = "2.1.1" @@ -7896,6 +7982,17 @@ dependencies = [ "utf-8", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -8742,6 +8839,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "universal-hash" version = "0.5.1" diff --git a/Changelog.md b/Changelog.md index 6e9e3e7d9..8cd23e78e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,7 @@ - windows 端监听关机信号失败 - 修复代理按钮和高亮状态不同步 - 修复侧边栏可能的未能正确跳转 +- 修复解锁测试部分地区图标编码不正确
✨ 新增功能 diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index c82208c42..84dfc513a 100755 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -98,6 +98,7 @@ clash_verge_service_ipc = { version = "2.0.21", features = [ ], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" } arc-swap = "1.7.1" rust-i18n = "3.1.5" +rust_iso3166 = "0.1.14" [target.'cfg(windows)'.dependencies] deelevate = { workspace = true } diff --git a/src-tauri/src/cmd/media_unlock_checker/utils.rs b/src-tauri/src/cmd/media_unlock_checker/utils.rs index c1852b4d8..0308b7dc0 100644 --- a/src-tauri/src/cmd/media_unlock_checker/utils.rs +++ b/src-tauri/src/cmd/media_unlock_checker/utils.rs @@ -1,4 +1,5 @@ use chrono::Local; +use rust_iso3166; pub fn get_local_date_string() -> String { let now = Local::now(); @@ -6,16 +7,70 @@ pub fn get_local_date_string() -> String { } pub fn country_code_to_emoji(country_code: &str) -> String { - let country_code = country_code.to_uppercase(); - if country_code.len() < 2 { - return String::new(); - } + let uc = country_code.to_ascii_uppercase(); - let bytes = country_code.as_bytes(); + // 长度校验:仅允许 2 或 3 + match uc.len() { + 2 => { + // 校验是否是合法 alpha2 + if rust_iso3166::from_alpha2(&uc).is_none() { + return String::new(); + } + alpha2_to_emoji(&uc) + } + 3 => { + // 转换并校验 alpha3 + match rust_iso3166::from_alpha3(&uc) { + Some(c) => { + let alpha2 = c.alpha2.to_ascii_uppercase(); + alpha2_to_emoji(&alpha2) + } + None => String::new(), + } + } + _ => String::new(), + } +} + +fn alpha2_to_emoji(alpha2: &str) -> String { + let bytes = alpha2.as_bytes(); let c1 = 0x1F1E6 + (bytes[0] as u32) - ('A' as u32); let c2 = 0x1F1E6 + (bytes[1] as u32) - ('A' as u32); - char::from_u32(c1) - .and_then(|c1| char::from_u32(c2).map(|c2| format!("{c1}{c2}"))) + .and_then(|x| char::from_u32(c2).map(|y| format!("{x}{y}"))) .unwrap_or_default() } + +#[cfg(test)] +mod tests { + use super::country_code_to_emoji; + + #[test] + fn country_code_to_emoji_iso2() { + assert_eq!(country_code_to_emoji("CN"), "🇨🇳"); + assert_eq!(country_code_to_emoji("us"), "🇺🇸"); + } + + #[test] + fn country_code_to_emoji_iso3() { + assert_eq!(country_code_to_emoji("CHN"), "🇨🇳"); + assert_eq!(country_code_to_emoji("USA"), "🇺🇸"); + } + + #[test] + fn country_code_to_emoji_invalid() { + assert_eq!(country_code_to_emoji("XXX"), ""); + assert_eq!(country_code_to_emoji("ZZ"), ""); + } + + #[test] + fn country_code_to_emoji_short() { + assert_eq!(country_code_to_emoji("C"), ""); + assert_eq!(country_code_to_emoji(""), ""); + } + + #[test] + fn country_code_to_emoji_long() { + assert_eq!(country_code_to_emoji("CNAAA"), ""); + } +}