use super::catalog;
pub trait LocalizedMsg {
fn message_key(&self) -> &'static str;
fn message_args(&self) -> Vec<(&str, String)> {
vec![]
}
}
pub trait I18nExt: LocalizedMsg + std::error::Error {
fn to_localized_string(&self) -> String {
catalog::translate(self.message_key(), &self.message_args())
}
fn message_en(&self) -> String {
catalog::translate_en(self.message_key(), &self.message_args())
}
}
impl<E: LocalizedMsg + std::error::Error> I18nExt for E {}
#[cfg(test)]
mod tests {
use super::*;
use crate::i18n::locale::{clear_locale_override, set_locale};
use std::fmt;
#[derive(Debug)]
struct TestError;
impl fmt::Display for TestError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "test error")
}
}
impl std::error::Error for TestError {}
impl LocalizedMsg for TestError {
fn message_key(&self) -> &'static str {
"pool-exhausted"
}
}
#[test]
fn test_to_localized_string_en() {
set_locale("en").unwrap();
let err = TestError;
assert_eq!(err.to_localized_string(), "Connection pool exhausted");
}
#[test]
fn test_to_localized_string_zh() {
set_locale("zh-CN").unwrap();
let err = TestError;
assert_eq!(err.to_localized_string(), "连接池已耗尽");
clear_locale_override();
}
#[test]
fn test_message_en_always_english() {
set_locale("zh-CN").unwrap();
let err = TestError;
assert_eq!(err.message_en(), "Connection pool exhausted");
clear_locale_override();
}
#[test]
fn test_to_string_still_english() {
set_locale("zh-CN").unwrap();
let err = TestError;
assert_eq!(err.to_string(), "test error");
clear_locale_override();
}
#[test]
fn test_message_key() {
let err = TestError;
assert_eq!(err.message_key(), "pool-exhausted");
}
#[test]
fn test_message_args_default_empty() {
let err = TestError;
assert!(err.message_args().is_empty());
}
}