use std::env;
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Lang {
#[default]
En,
Zh,
}
impl Lang {
pub fn detect() -> Self {
for key in ["LC_ALL", "LC_MESSAGES", "LANG"] {
if let Ok(v) = env::var(key) {
let v = v.trim().to_ascii_lowercase();
if v.starts_with("zh") {
return Lang::Zh;
}
if !v.is_empty() {
return Lang::En;
}
}
}
Lang::En
}
pub fn parse_arg(s: &str) -> Self {
let s = s.trim().to_ascii_lowercase();
if s.starts_with("zh") || s == "cn" || s == "chinese" {
Lang::Zh
} else {
Lang::En
}
}
pub fn strings(self) -> &'static Strings {
match self {
Lang::En => &EN,
Lang::Zh => &ZH,
}
}
}
#[derive(Debug)]
pub struct Strings {
pub connected_to: &'static str,
pub resolved_to: &'static str,
pub error_label: &'static str,
pub fail: &'static str,
pub grpc_ok: &'static str,
pub dns_lookup: &'static str,
pub dns_connect: &'static str,
pub dns_query: &'static str,
pub tcp_connect: &'static str,
pub tls_handshake: &'static str,
pub quic_connect: &'static str,
pub request_send: &'static str,
pub server_processing: &'static str,
pub server_processing_short: &'static str,
pub content_transfer: &'static str,
pub content_transfer_short: &'static str,
pub total: &'static str,
pub tls_label: &'static str,
pub cipher: &'static str,
pub handshake: &'static str,
pub handshake_full: &'static str,
pub handshake_resumed: &'static str,
pub early_data: &'static str,
pub early_data_accepted: &'static str,
pub early_data_not_accepted: &'static str,
pub ocsp: &'static str,
pub ocsp_stapled: &'static str,
pub ocsp_not_stapled: &'static str,
pub not_before: &'static str,
pub not_after: &'static str,
pub subject: &'static str,
pub issuer: &'static str,
pub cert_domains: &'static str,
pub cert_chain: &'static str,
pub server_timing_heading: &'static str,
pub st_sum_of: &'static str,
pub st_unaccounted: &'static str,
pub protocol_adv_heading: &'static str,
pub alt_svc_label: &'static str,
pub hsts_label: &'static str,
pub kernel_tcp_heading: &'static str,
pub tcp_post_connect_row: &'static str,
pub tcp_final_row: &'static str,
pub tcp_during: &'static str,
pub tcp_retransmit_word: &'static str,
pub body_size: &'static str,
pub body_discarded: &'static str,
pub saved_to: &'static str,
pub throughput: &'static str,
pub throughput_first_100k: &'static str,
pub throughput_then: &'static str,
pub benchmark_results_prefix: &'static str,
pub benchmark_results_requests: &'static str,
pub success: &'static str,
pub cold_connect: &'static str,
pub min: &'static str,
pub max: &'static str,
pub avg: &'static str,
}
pub const EN: Strings = Strings {
connected_to: "Connected to",
resolved_to: "Resolved to",
error_label: "Error",
fail: "FAIL",
grpc_ok: "GRPC OK",
dns_lookup: "DNS Lookup",
dns_connect: "DNS Connect",
dns_query: "DNS Query",
tcp_connect: "TCP Connect",
tls_handshake: "TLS Handshake",
quic_connect: "QUIC Connect",
request_send: "Request Send",
server_processing: "Server Processing",
server_processing_short: "Server Process",
content_transfer: "Content Transfer",
content_transfer_short: "Content Xfer",
total: "Total",
tls_label: "Tls",
cipher: "Cipher",
handshake: "Handshake",
handshake_full: "Full",
handshake_resumed: "Resumed",
early_data: "Early Data",
early_data_accepted: "accepted (0-RTT)",
early_data_not_accepted: "not accepted",
ocsp: "OCSP",
ocsp_stapled: "stapled",
ocsp_not_stapled: "not stapled",
not_before: "Not Before",
not_after: "Not After",
subject: "Subject",
issuer: "Issuer",
cert_domains: "Certificate Domains",
cert_chain: "Certificate Chain",
server_timing_heading: "Server-Timing:",
st_sum_of: "of",
st_unaccounted: "unaccounted",
protocol_adv_heading: "Server Advertisements:",
alt_svc_label: "Alt-Svc:",
hsts_label: "HSTS: ",
kernel_tcp_heading: "Kernel TCP:",
tcp_post_connect_row: "post-connect:",
tcp_final_row: "final:",
tcp_during: "during request:",
tcp_retransmit_word: "retransmit(s)",
body_size: "Body size",
body_discarded: "Body discarded",
saved_to: "saved to",
throughput: "Throughput:",
throughput_first_100k: "first 100KB:",
throughput_then: "then:",
benchmark_results_prefix: "--- Benchmark Results",
benchmark_results_requests: "requests",
success: "Success",
cold_connect: "Cold connect",
min: "min",
max: "max",
avg: "avg",
};
pub const ZH: Strings = Strings {
connected_to: "已连接到",
resolved_to: "已解析到",
error_label: "错误",
fail: "失败",
grpc_ok: "gRPC 正常",
dns_lookup: "DNS 解析",
dns_connect: "DNS 连接",
dns_query: "DNS 查询",
tcp_connect: "TCP 连接",
tls_handshake: "TLS 握手",
quic_connect: "QUIC 连接",
request_send: "请求发送",
server_processing: "服务端处理",
server_processing_short: "服务端处理",
content_transfer: "内容传输",
content_transfer_short: "内容传输",
total: "总耗时",
tls_label: "TLS",
cipher: "加密套件",
handshake: "握手",
handshake_full: "完整",
handshake_resumed: "复用",
early_data: "早期数据",
early_data_accepted: "已接受 (0-RTT)",
early_data_not_accepted: "未接受",
ocsp: "OCSP",
ocsp_stapled: "已 staple",
ocsp_not_stapled: "未 staple",
not_before: "生效时间",
not_after: "到期时间",
subject: "主体",
issuer: "颁发者",
cert_domains: "证书域名",
cert_chain: "证书链",
server_timing_heading: "Server-Timing:",
st_sum_of: "占",
st_unaccounted: "未统计",
protocol_adv_heading: "服务器声明:",
alt_svc_label: "Alt-Svc:",
hsts_label: "HSTS: ",
kernel_tcp_heading: "内核 TCP:",
tcp_post_connect_row: "连接后:",
tcp_final_row: "完成时:",
tcp_during: "本次请求:",
tcp_retransmit_word: "次重传",
body_size: "响应体大小",
body_discarded: "响应体已丢弃",
saved_to: "已保存到",
throughput: "吞吐:",
throughput_first_100k: "首 100KB:",
throughput_then: "之后:",
benchmark_results_prefix: "--- 基准测试结果",
benchmark_results_requests: "次请求",
success: "成功",
cold_connect: "冷连接",
min: "最小",
max: "最大",
avg: "均值",
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_arg_maps_languages() {
assert_eq!(Lang::parse_arg("zh"), Lang::Zh);
assert_eq!(Lang::parse_arg("ZH-CN"), Lang::Zh);
assert_eq!(Lang::parse_arg("zh_TW"), Lang::Zh);
assert_eq!(Lang::parse_arg("cn"), Lang::Zh);
assert_eq!(Lang::parse_arg("chinese"), Lang::Zh);
assert_eq!(Lang::parse_arg("en"), Lang::En);
assert_eq!(Lang::parse_arg("fr"), Lang::En); assert_eq!(Lang::parse_arg(""), Lang::En);
}
}