mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
fix: correct flag emoji for ISO alpha-3 region code (#5557)
* fix: correct flag emoji for ISO alpha-3 region code * fix: use rust_iso3166 to convert ISO3 region code * fix: validate ISO country code when generating flag emoji * fix: correct icon encoding for unlock test in specific regions --------- Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
This commit is contained in:
103
Cargo.lock
generated
103
Cargo.lock
generated
@@ -1144,6 +1144,7 @@ dependencies = [
|
|||||||
"reqwest_dav",
|
"reqwest_dav",
|
||||||
"runas",
|
"runas",
|
||||||
"rust-i18n",
|
"rust-i18n",
|
||||||
|
"rust_iso3166",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -1664,6 +1665,27 @@ dependencies = [
|
|||||||
"syn 2.0.111",
|
"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]]
|
[[package]]
|
||||||
name = "ctor"
|
name = "ctor"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
@@ -1935,6 +1957,16 @@ dependencies = [
|
|||||||
"dirs-sys 0.5.0",
|
"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]]
|
[[package]]
|
||||||
name = "dirs-sys"
|
name = "dirs-sys"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@@ -1958,6 +1990,17 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"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]]
|
[[package]]
|
||||||
name = "dispatch"
|
name = "dispatch"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -2131,6 +2174,12 @@ version = "1.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
|
checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encode_unicode"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.35"
|
version = "0.8.35"
|
||||||
@@ -3719,6 +3768,17 @@ dependencies = [
|
|||||||
"once_cell",
|
"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]]
|
[[package]]
|
||||||
name = "is-wsl"
|
name = "is-wsl"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@@ -5561,6 +5621,20 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
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]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
@@ -6303,6 +6377,18 @@ dependencies = [
|
|||||||
"ordered-multimap",
|
"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]]
|
[[package]]
|
||||||
name = "rustc-hash"
|
name = "rustc-hash"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
@@ -7896,6 +7982,17 @@ dependencies = [
|
|||||||
"utf-8",
|
"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]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
@@ -8742,6 +8839,12 @@ version = "1.12.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "universal-hash"
|
name = "universal-hash"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
- windows 端监听关机信号失败
|
- windows 端监听关机信号失败
|
||||||
- 修复代理按钮和高亮状态不同步
|
- 修复代理按钮和高亮状态不同步
|
||||||
- 修复侧边栏可能的未能正确跳转
|
- 修复侧边栏可能的未能正确跳转
|
||||||
|
- 修复解锁测试部分地区图标编码不正确
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><strong> ✨ 新增功能 </strong></summary>
|
<summary><strong> ✨ 新增功能 </strong></summary>
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ clash_verge_service_ipc = { version = "2.0.21", features = [
|
|||||||
], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" }
|
], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" }
|
||||||
arc-swap = "1.7.1"
|
arc-swap = "1.7.1"
|
||||||
rust-i18n = "3.1.5"
|
rust-i18n = "3.1.5"
|
||||||
|
rust_iso3166 = "0.1.14"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
deelevate = { workspace = true }
|
deelevate = { workspace = true }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
|
use rust_iso3166;
|
||||||
|
|
||||||
pub fn get_local_date_string() -> String {
|
pub fn get_local_date_string() -> String {
|
||||||
let now = Local::now();
|
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 {
|
pub fn country_code_to_emoji(country_code: &str) -> String {
|
||||||
let country_code = country_code.to_uppercase();
|
let uc = country_code.to_ascii_uppercase();
|
||||||
if country_code.len() < 2 {
|
|
||||||
return String::new();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 c1 = 0x1F1E6 + (bytes[0] as u32) - ('A' as u32);
|
||||||
let c2 = 0x1F1E6 + (bytes[1] as u32) - ('A' as u32);
|
let c2 = 0x1F1E6 + (bytes[1] as u32) - ('A' as u32);
|
||||||
|
|
||||||
char::from_u32(c1)
|
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()
|
.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"), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user