feat(render): add support for localized dates. Fix #156
This commit is contained in:
parent
ec24100260
commit
36a507488b
37
Cargo.lock
generated
37
Cargo.lock
generated
|
@ -212,6 +212,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"pure-rust-locales",
|
||||||
"time",
|
"time",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
@ -399,6 +400,16 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cstr_core"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "644828c273c063ab0d39486ba42a5d1f3a499d35529c759e763a9c6cb8a0fb08"
|
||||||
|
dependencies = [
|
||||||
|
"cty",
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctor"
|
name = "ctor"
|
||||||
version = "0.1.20"
|
version = "0.1.20"
|
||||||
|
@ -409,6 +420,12 @@ dependencies = [
|
||||||
"syn 1.0.67",
|
"syn 1.0.67",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cty"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dbus"
|
name = "dbus"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
|
@ -851,6 +868,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"regex",
|
"regex",
|
||||||
|
"sys-locale",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2040,6 +2058,12 @@ dependencies = [
|
||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pure-rust-locales"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b45c49fc4f91f35bae654f85ebb3a44d60ac64f11b3166ffa609def390c732d8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
@ -2577,6 +2601,19 @@ dependencies = [
|
||||||
"unicode-xid 0.0.4",
|
"unicode-xid 0.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sys-locale"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91f89ebb59fa30d4f65fafc2d68e94f6975256fd87e812dd99cb6e020c8563df"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cstr_core",
|
||||||
|
"libc",
|
||||||
|
"web-sys",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempdir"
|
name = "tempdir"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
|
|
|
@ -10,6 +10,7 @@ anyhow = "1.0.38"
|
||||||
thiserror = "1.0.23"
|
thiserror = "1.0.23"
|
||||||
regex = "1.4.3"
|
regex = "1.4.3"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
chrono = "0.4.19"
|
chrono = {version = "0.4.19", features=["unstable-locales"]}
|
||||||
enum-as-inner = "0.3.3"
|
enum-as-inner = "0.3.3"
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
|
sys-locale = "0.1.0"
|
|
@ -17,22 +17,30 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use chrono::{DateTime, Duration, Local};
|
use chrono::{DateTime, Duration, Local, Locale};
|
||||||
|
|
||||||
use crate::{Extension, ExtensionOutput, ExtensionResult, Number, Params, Value};
|
use crate::{Extension, ExtensionOutput, ExtensionResult, Number, Params, Value};
|
||||||
|
|
||||||
pub struct DateExtension {
|
pub trait LocaleProvider {
|
||||||
|
fn get_system_locale(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DateExtension<'a> {
|
||||||
fixed_date: Option<DateTime<Local>>,
|
fixed_date: Option<DateTime<Local>>,
|
||||||
|
locale_provider: &'a dyn LocaleProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::new_without_default)]
|
#[allow(clippy::new_without_default)]
|
||||||
impl DateExtension {
|
impl<'a> DateExtension<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new(locale_provider: &'a dyn LocaleProvider) -> Self {
|
||||||
Self { fixed_date: None }
|
Self {
|
||||||
|
fixed_date: None,
|
||||||
|
locale_provider,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Extension for DateExtension {
|
impl<'a> Extension for DateExtension<'a> {
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"date"
|
"date"
|
||||||
}
|
}
|
||||||
|
@ -53,9 +61,14 @@ impl Extension for DateExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
let format = params.get("format");
|
let format = params.get("format");
|
||||||
|
let locale = params
|
||||||
|
.get("locale")
|
||||||
|
.and_then(|val| val.as_string())
|
||||||
|
.map(String::from)
|
||||||
|
.unwrap_or_else(|| self.locale_provider.get_system_locale());
|
||||||
|
|
||||||
let date = if let Some(Value::String(format)) = format {
|
let date = if let Some(Value::String(format)) = format {
|
||||||
now.format(format).to_string()
|
DateExtension::format_date_with_locale_string(now, format, &locale)
|
||||||
} else {
|
} else {
|
||||||
now.to_rfc2822()
|
now.to_rfc2822()
|
||||||
};
|
};
|
||||||
|
@ -64,7 +77,7 @@ impl Extension for DateExtension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DateExtension {
|
impl<'a> DateExtension<'a> {
|
||||||
fn get_date(&self) -> DateTime<Local> {
|
fn get_date(&self) -> DateTime<Local> {
|
||||||
if let Some(fixed_date) = self.fixed_date {
|
if let Some(fixed_date) = self.fixed_date {
|
||||||
fixed_date
|
fixed_date
|
||||||
|
@ -72,6 +85,339 @@ impl DateExtension {
|
||||||
Local::now()
|
Local::now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn format_date_with_locale(date: DateTime<Local>, format: &str, locale: Locale) -> String {
|
||||||
|
date.format_localized(format, locale).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_date_with_locale_string(
|
||||||
|
date: DateTime<Local>,
|
||||||
|
format: &str,
|
||||||
|
locale_str: &str,
|
||||||
|
) -> String {
|
||||||
|
let locale = convert_locale_string_to_locale(locale_str).unwrap_or(Locale::en_US);
|
||||||
|
Self::format_date_with_locale(date, format, locale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_locale_string_to_locale(locale_str: &str) -> Option<Locale> {
|
||||||
|
match locale_str {
|
||||||
|
"aa-DJ" => Some(Locale::aa_DJ),
|
||||||
|
"aa-ER" => Some(Locale::aa_ER),
|
||||||
|
"aa-ET" => Some(Locale::aa_ET),
|
||||||
|
"af-ZA" => Some(Locale::af_ZA),
|
||||||
|
"agr-PE" => Some(Locale::agr_PE),
|
||||||
|
"ak-GH" => Some(Locale::ak_GH),
|
||||||
|
"am-ET" => Some(Locale::am_ET),
|
||||||
|
"an-ES" => Some(Locale::an_ES),
|
||||||
|
"anp-IN" => Some(Locale::anp_IN),
|
||||||
|
"ar-AE" => Some(Locale::ar_AE),
|
||||||
|
"ar-BH" => Some(Locale::ar_BH),
|
||||||
|
"ar-DZ" => Some(Locale::ar_DZ),
|
||||||
|
"ar-EG" => Some(Locale::ar_EG),
|
||||||
|
"ar-IN" => Some(Locale::ar_IN),
|
||||||
|
"ar-IQ" => Some(Locale::ar_IQ),
|
||||||
|
"ar-JO" => Some(Locale::ar_JO),
|
||||||
|
"ar-KW" => Some(Locale::ar_KW),
|
||||||
|
"ar-LB" => Some(Locale::ar_LB),
|
||||||
|
"ar-LY" => Some(Locale::ar_LY),
|
||||||
|
"ar-MA" => Some(Locale::ar_MA),
|
||||||
|
"ar-OM" => Some(Locale::ar_OM),
|
||||||
|
"ar-QA" => Some(Locale::ar_QA),
|
||||||
|
"ar-SA" => Some(Locale::ar_SA),
|
||||||
|
"ar-SD" => Some(Locale::ar_SD),
|
||||||
|
"ar-SS" => Some(Locale::ar_SS),
|
||||||
|
"ar-SY" => Some(Locale::ar_SY),
|
||||||
|
"ar-TN" => Some(Locale::ar_TN),
|
||||||
|
"ar-YE" => Some(Locale::ar_YE),
|
||||||
|
"as-IN" => Some(Locale::as_IN),
|
||||||
|
"ast-ES" => Some(Locale::ast_ES),
|
||||||
|
"ayc-PE" => Some(Locale::ayc_PE),
|
||||||
|
"az-AZ" => Some(Locale::az_AZ),
|
||||||
|
"az-IR" => Some(Locale::az_IR),
|
||||||
|
"be-BY" => Some(Locale::be_BY),
|
||||||
|
"bem-ZM" => Some(Locale::bem_ZM),
|
||||||
|
"ber-DZ" => Some(Locale::ber_DZ),
|
||||||
|
"ber-MA" => Some(Locale::ber_MA),
|
||||||
|
"bg-BG" => Some(Locale::bg_BG),
|
||||||
|
"bhb-IN" => Some(Locale::bhb_IN),
|
||||||
|
"bho-IN" => Some(Locale::bho_IN),
|
||||||
|
"bho-NP" => Some(Locale::bho_NP),
|
||||||
|
"bi-VU" => Some(Locale::bi_VU),
|
||||||
|
"bn-BD" => Some(Locale::bn_BD),
|
||||||
|
"bn-IN" => Some(Locale::bn_IN),
|
||||||
|
"bo-CN" => Some(Locale::bo_CN),
|
||||||
|
"bo-IN" => Some(Locale::bo_IN),
|
||||||
|
"br-FR" => Some(Locale::br_FR),
|
||||||
|
"brx-IN" => Some(Locale::brx_IN),
|
||||||
|
"bs-BA" => Some(Locale::bs_BA),
|
||||||
|
"byn-ER" => Some(Locale::byn_ER),
|
||||||
|
"ca-AD" => Some(Locale::ca_AD),
|
||||||
|
"ca-ES" => Some(Locale::ca_ES),
|
||||||
|
"ca-FR" => Some(Locale::ca_FR),
|
||||||
|
"ca-IT" => Some(Locale::ca_IT),
|
||||||
|
"ce-RU" => Some(Locale::ce_RU),
|
||||||
|
"chr-US" => Some(Locale::chr_US),
|
||||||
|
"cmn-TW" => Some(Locale::cmn_TW),
|
||||||
|
"crh-UA" => Some(Locale::crh_UA),
|
||||||
|
"cs-CZ" => Some(Locale::cs_CZ),
|
||||||
|
"csb-PL" => Some(Locale::csb_PL),
|
||||||
|
"cv-RU" => Some(Locale::cv_RU),
|
||||||
|
"cy-GB" => Some(Locale::cy_GB),
|
||||||
|
"da-DK" => Some(Locale::da_DK),
|
||||||
|
"de-AT" => Some(Locale::de_AT),
|
||||||
|
"de-BE" => Some(Locale::de_BE),
|
||||||
|
"de-CH" => Some(Locale::de_CH),
|
||||||
|
"de-DE" => Some(Locale::de_DE),
|
||||||
|
"de-IT" => Some(Locale::de_IT),
|
||||||
|
"de-LI" => Some(Locale::de_LI),
|
||||||
|
"de-LU" => Some(Locale::de_LU),
|
||||||
|
"doi-IN" => Some(Locale::doi_IN),
|
||||||
|
"dsb-DE" => Some(Locale::dsb_DE),
|
||||||
|
"dv-MV" => Some(Locale::dv_MV),
|
||||||
|
"dz-BT" => Some(Locale::dz_BT),
|
||||||
|
"el-CY" => Some(Locale::el_CY),
|
||||||
|
"el-GR" => Some(Locale::el_GR),
|
||||||
|
"en-AG" => Some(Locale::en_AG),
|
||||||
|
"en-AU" => Some(Locale::en_AU),
|
||||||
|
"en-BW" => Some(Locale::en_BW),
|
||||||
|
"en-CA" => Some(Locale::en_CA),
|
||||||
|
"en-DK" => Some(Locale::en_DK),
|
||||||
|
"en-GB" => Some(Locale::en_GB),
|
||||||
|
"en-HK" => Some(Locale::en_HK),
|
||||||
|
"en-IE" => Some(Locale::en_IE),
|
||||||
|
"en-IL" => Some(Locale::en_IL),
|
||||||
|
"en-IN" => Some(Locale::en_IN),
|
||||||
|
"en-NG" => Some(Locale::en_NG),
|
||||||
|
"en-NZ" => Some(Locale::en_NZ),
|
||||||
|
"en-PH" => Some(Locale::en_PH),
|
||||||
|
"en-SC" => Some(Locale::en_SC),
|
||||||
|
"en-SG" => Some(Locale::en_SG),
|
||||||
|
"en-US" => Some(Locale::en_US),
|
||||||
|
"en-ZA" => Some(Locale::en_ZA),
|
||||||
|
"en-ZM" => Some(Locale::en_ZM),
|
||||||
|
"en-ZW" => Some(Locale::en_ZW),
|
||||||
|
"eo" => Some(Locale::eo),
|
||||||
|
"es-AR" => Some(Locale::es_AR),
|
||||||
|
"es-BO" => Some(Locale::es_BO),
|
||||||
|
"es-CL" => Some(Locale::es_CL),
|
||||||
|
"es-CO" => Some(Locale::es_CO),
|
||||||
|
"es-CR" => Some(Locale::es_CR),
|
||||||
|
"es-CU" => Some(Locale::es_CU),
|
||||||
|
"es-DO" => Some(Locale::es_DO),
|
||||||
|
"es-EC" => Some(Locale::es_EC),
|
||||||
|
"es-ES" => Some(Locale::es_ES),
|
||||||
|
"es-GT" => Some(Locale::es_GT),
|
||||||
|
"es-HN" => Some(Locale::es_HN),
|
||||||
|
"es-MX" => Some(Locale::es_MX),
|
||||||
|
"es-NI" => Some(Locale::es_NI),
|
||||||
|
"es-PA" => Some(Locale::es_PA),
|
||||||
|
"es-PE" => Some(Locale::es_PE),
|
||||||
|
"es-PR" => Some(Locale::es_PR),
|
||||||
|
"es-PY" => Some(Locale::es_PY),
|
||||||
|
"es-SV" => Some(Locale::es_SV),
|
||||||
|
"es-US" => Some(Locale::es_US),
|
||||||
|
"es-UY" => Some(Locale::es_UY),
|
||||||
|
"es-VE" => Some(Locale::es_VE),
|
||||||
|
"et-EE" => Some(Locale::et_EE),
|
||||||
|
"eu-ES" => Some(Locale::eu_ES),
|
||||||
|
"fa-IR" => Some(Locale::fa_IR),
|
||||||
|
"ff-SN" => Some(Locale::ff_SN),
|
||||||
|
"fi-FI" => Some(Locale::fi_FI),
|
||||||
|
"fil-PH" => Some(Locale::fil_PH),
|
||||||
|
"fo-FO" => Some(Locale::fo_FO),
|
||||||
|
"fr-BE" => Some(Locale::fr_BE),
|
||||||
|
"fr-CA" => Some(Locale::fr_CA),
|
||||||
|
"fr-CH" => Some(Locale::fr_CH),
|
||||||
|
"fr-FR" => Some(Locale::fr_FR),
|
||||||
|
"fr-LU" => Some(Locale::fr_LU),
|
||||||
|
"fur-IT" => Some(Locale::fur_IT),
|
||||||
|
"fy-DE" => Some(Locale::fy_DE),
|
||||||
|
"fy-NL" => Some(Locale::fy_NL),
|
||||||
|
"ga-IE" => Some(Locale::ga_IE),
|
||||||
|
"gd-GB" => Some(Locale::gd_GB),
|
||||||
|
"gez-ER" => Some(Locale::gez_ER),
|
||||||
|
"gez-ET" => Some(Locale::gez_ET),
|
||||||
|
"gl-ES" => Some(Locale::gl_ES),
|
||||||
|
"gu-IN" => Some(Locale::gu_IN),
|
||||||
|
"gv-GB" => Some(Locale::gv_GB),
|
||||||
|
"ha-NG" => Some(Locale::ha_NG),
|
||||||
|
"hak-TW" => Some(Locale::hak_TW),
|
||||||
|
"he-IL" => Some(Locale::he_IL),
|
||||||
|
"hi-IN" => Some(Locale::hi_IN),
|
||||||
|
"hif-FJ" => Some(Locale::hif_FJ),
|
||||||
|
"hne-IN" => Some(Locale::hne_IN),
|
||||||
|
"hr-HR" => Some(Locale::hr_HR),
|
||||||
|
"hsb-DE" => Some(Locale::hsb_DE),
|
||||||
|
"ht-HT" => Some(Locale::ht_HT),
|
||||||
|
"hu-HU" => Some(Locale::hu_HU),
|
||||||
|
"hy-AM" => Some(Locale::hy_AM),
|
||||||
|
"ia-FR" => Some(Locale::ia_FR),
|
||||||
|
"id-ID" => Some(Locale::id_ID),
|
||||||
|
"ig-NG" => Some(Locale::ig_NG),
|
||||||
|
"ik-CA" => Some(Locale::ik_CA),
|
||||||
|
"is-IS" => Some(Locale::is_IS),
|
||||||
|
"it-CH" => Some(Locale::it_CH),
|
||||||
|
"it-IT" => Some(Locale::it_IT),
|
||||||
|
"iu-CA" => Some(Locale::iu_CA),
|
||||||
|
"ja-JP" => Some(Locale::ja_JP),
|
||||||
|
"ka-GE" => Some(Locale::ka_GE),
|
||||||
|
"kab-DZ" => Some(Locale::kab_DZ),
|
||||||
|
"kk-KZ" => Some(Locale::kk_KZ),
|
||||||
|
"kl-GL" => Some(Locale::kl_GL),
|
||||||
|
"km-KH" => Some(Locale::km_KH),
|
||||||
|
"kn-IN" => Some(Locale::kn_IN),
|
||||||
|
"ko-KR" => Some(Locale::ko_KR),
|
||||||
|
"kok-IN" => Some(Locale::kok_IN),
|
||||||
|
"ks-IN" => Some(Locale::ks_IN),
|
||||||
|
"ku-TR" => Some(Locale::ku_TR),
|
||||||
|
"kw-GB" => Some(Locale::kw_GB),
|
||||||
|
"ky-KG" => Some(Locale::ky_KG),
|
||||||
|
"lb-LU" => Some(Locale::lb_LU),
|
||||||
|
"lg-UG" => Some(Locale::lg_UG),
|
||||||
|
"li-BE" => Some(Locale::li_BE),
|
||||||
|
"li-NL" => Some(Locale::li_NL),
|
||||||
|
"lij-IT" => Some(Locale::lij_IT),
|
||||||
|
"ln-CD" => Some(Locale::ln_CD),
|
||||||
|
"lo-LA" => Some(Locale::lo_LA),
|
||||||
|
"lt-LT" => Some(Locale::lt_LT),
|
||||||
|
"lv-LV" => Some(Locale::lv_LV),
|
||||||
|
"lzh-TW" => Some(Locale::lzh_TW),
|
||||||
|
"mag-IN" => Some(Locale::mag_IN),
|
||||||
|
"mai-IN" => Some(Locale::mai_IN),
|
||||||
|
"mai-NP" => Some(Locale::mai_NP),
|
||||||
|
"mfe-MU" => Some(Locale::mfe_MU),
|
||||||
|
"mg-MG" => Some(Locale::mg_MG),
|
||||||
|
"mhr-RU" => Some(Locale::mhr_RU),
|
||||||
|
"mi-NZ" => Some(Locale::mi_NZ),
|
||||||
|
"miq-NI" => Some(Locale::miq_NI),
|
||||||
|
"mjw-IN" => Some(Locale::mjw_IN),
|
||||||
|
"mk-MK" => Some(Locale::mk_MK),
|
||||||
|
"ml-IN" => Some(Locale::ml_IN),
|
||||||
|
"mn-MN" => Some(Locale::mn_MN),
|
||||||
|
"mni-IN" => Some(Locale::mni_IN),
|
||||||
|
"mnw-MM" => Some(Locale::mnw_MM),
|
||||||
|
"mr-IN" => Some(Locale::mr_IN),
|
||||||
|
"ms-MY" => Some(Locale::ms_MY),
|
||||||
|
"mt-MT" => Some(Locale::mt_MT),
|
||||||
|
"my-MM" => Some(Locale::my_MM),
|
||||||
|
"nan-TW" => Some(Locale::nan_TW),
|
||||||
|
"nb-NO" => Some(Locale::nb_NO),
|
||||||
|
"nds-DE" => Some(Locale::nds_DE),
|
||||||
|
"nds-NL" => Some(Locale::nds_NL),
|
||||||
|
"ne-NP" => Some(Locale::ne_NP),
|
||||||
|
"nhn-MX" => Some(Locale::nhn_MX),
|
||||||
|
"niu-NU" => Some(Locale::niu_NU),
|
||||||
|
"niu-NZ" => Some(Locale::niu_NZ),
|
||||||
|
"nl-AW" => Some(Locale::nl_AW),
|
||||||
|
"nl-BE" => Some(Locale::nl_BE),
|
||||||
|
"nl-NL" => Some(Locale::nl_NL),
|
||||||
|
"nn-NO" => Some(Locale::nn_NO),
|
||||||
|
"nr-ZA" => Some(Locale::nr_ZA),
|
||||||
|
"nso-ZA" => Some(Locale::nso_ZA),
|
||||||
|
"oc-FR" => Some(Locale::oc_FR),
|
||||||
|
"om-ET" => Some(Locale::om_ET),
|
||||||
|
"om-KE" => Some(Locale::om_KE),
|
||||||
|
"or-IN" => Some(Locale::or_IN),
|
||||||
|
"os-RU" => Some(Locale::os_RU),
|
||||||
|
"pa-IN" => Some(Locale::pa_IN),
|
||||||
|
"pa-PK" => Some(Locale::pa_PK),
|
||||||
|
"pap-AW" => Some(Locale::pap_AW),
|
||||||
|
"pap-CW" => Some(Locale::pap_CW),
|
||||||
|
"pl-PL" => Some(Locale::pl_PL),
|
||||||
|
"ps-AF" => Some(Locale::ps_AF),
|
||||||
|
"pt-BR" => Some(Locale::pt_BR),
|
||||||
|
"pt-PT" => Some(Locale::pt_PT),
|
||||||
|
"quz-PE" => Some(Locale::quz_PE),
|
||||||
|
"raj-IN" => Some(Locale::raj_IN),
|
||||||
|
"ro-RO" => Some(Locale::ro_RO),
|
||||||
|
"ru-RU" => Some(Locale::ru_RU),
|
||||||
|
"ru-UA" => Some(Locale::ru_UA),
|
||||||
|
"rw-RW" => Some(Locale::rw_RW),
|
||||||
|
"sa-IN" => Some(Locale::sa_IN),
|
||||||
|
"sah-RU" => Some(Locale::sah_RU),
|
||||||
|
"sat-IN" => Some(Locale::sat_IN),
|
||||||
|
"sc-IT" => Some(Locale::sc_IT),
|
||||||
|
"sd-IN" => Some(Locale::sd_IN),
|
||||||
|
"se-NO" => Some(Locale::se_NO),
|
||||||
|
"sgs-LT" => Some(Locale::sgs_LT),
|
||||||
|
"shn-MM" => Some(Locale::shn_MM),
|
||||||
|
"shs-CA" => Some(Locale::shs_CA),
|
||||||
|
"si-LK" => Some(Locale::si_LK),
|
||||||
|
"sid-ET" => Some(Locale::sid_ET),
|
||||||
|
"sk-SK" => Some(Locale::sk_SK),
|
||||||
|
"sl-SI" => Some(Locale::sl_SI),
|
||||||
|
"sm-WS" => Some(Locale::sm_WS),
|
||||||
|
"so-DJ" => Some(Locale::so_DJ),
|
||||||
|
"so-ET" => Some(Locale::so_ET),
|
||||||
|
"so-KE" => Some(Locale::so_KE),
|
||||||
|
"so-SO" => Some(Locale::so_SO),
|
||||||
|
"sq-AL" => Some(Locale::sq_AL),
|
||||||
|
"sq-MK" => Some(Locale::sq_MK),
|
||||||
|
"sr-ME" => Some(Locale::sr_ME),
|
||||||
|
"sr-RS" => Some(Locale::sr_RS),
|
||||||
|
"ss-ZA" => Some(Locale::ss_ZA),
|
||||||
|
"st-ZA" => Some(Locale::st_ZA),
|
||||||
|
"sv-FI" => Some(Locale::sv_FI),
|
||||||
|
"sv-SE" => Some(Locale::sv_SE),
|
||||||
|
"sw-KE" => Some(Locale::sw_KE),
|
||||||
|
"sw-TZ" => Some(Locale::sw_TZ),
|
||||||
|
"szl-PL" => Some(Locale::szl_PL),
|
||||||
|
"ta-IN" => Some(Locale::ta_IN),
|
||||||
|
"ta-LK" => Some(Locale::ta_LK),
|
||||||
|
"tcy-IN" => Some(Locale::tcy_IN),
|
||||||
|
"te-IN" => Some(Locale::te_IN),
|
||||||
|
"tg-TJ" => Some(Locale::tg_TJ),
|
||||||
|
"th-TH" => Some(Locale::th_TH),
|
||||||
|
"the-NP" => Some(Locale::the_NP),
|
||||||
|
"ti-ER" => Some(Locale::ti_ER),
|
||||||
|
"ti-ET" => Some(Locale::ti_ET),
|
||||||
|
"tig-ER" => Some(Locale::tig_ER),
|
||||||
|
"tk-TM" => Some(Locale::tk_TM),
|
||||||
|
"tl-PH" => Some(Locale::tl_PH),
|
||||||
|
"tn-ZA" => Some(Locale::tn_ZA),
|
||||||
|
"to-TO" => Some(Locale::to_TO),
|
||||||
|
"tpi-PG" => Some(Locale::tpi_PG),
|
||||||
|
"tr-CY" => Some(Locale::tr_CY),
|
||||||
|
"tr-TR" => Some(Locale::tr_TR),
|
||||||
|
"ts-ZA" => Some(Locale::ts_ZA),
|
||||||
|
"tt-RU" => Some(Locale::tt_RU),
|
||||||
|
"ug-CN" => Some(Locale::ug_CN),
|
||||||
|
"uk-UA" => Some(Locale::uk_UA),
|
||||||
|
"unm-US" => Some(Locale::unm_US),
|
||||||
|
"ur-IN" => Some(Locale::ur_IN),
|
||||||
|
"ur-PK" => Some(Locale::ur_PK),
|
||||||
|
"uz-UZ" => Some(Locale::uz_UZ),
|
||||||
|
"ve-ZA" => Some(Locale::ve_ZA),
|
||||||
|
"vi-VN" => Some(Locale::vi_VN),
|
||||||
|
"wa-BE" => Some(Locale::wa_BE),
|
||||||
|
"wae-CH" => Some(Locale::wae_CH),
|
||||||
|
"wal-ET" => Some(Locale::wal_ET),
|
||||||
|
"wo-SN" => Some(Locale::wo_SN),
|
||||||
|
"xh-ZA" => Some(Locale::xh_ZA),
|
||||||
|
"yi-US" => Some(Locale::yi_US),
|
||||||
|
"yo-NG" => Some(Locale::yo_NG),
|
||||||
|
"yue-HK" => Some(Locale::yue_HK),
|
||||||
|
"yuw-PG" => Some(Locale::yuw_PG),
|
||||||
|
"zh-CN" => Some(Locale::zh_CN),
|
||||||
|
"zh-HK" => Some(Locale::zh_HK),
|
||||||
|
"zh-SG" => Some(Locale::zh_SG),
|
||||||
|
"zh-TW" => Some(Locale::zh_TW),
|
||||||
|
"zu-ZA" => Some(Locale::zu_ZA),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DefaultLocaleProvider {}
|
||||||
|
impl LocaleProvider for DefaultLocaleProvider {
|
||||||
|
fn get_system_locale(&self) -> String {
|
||||||
|
sys_locale::get_locale().unwrap_or_else(|| String::from("en-US"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl DefaultLocaleProvider {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -79,9 +425,30 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use chrono::offset::TimeZone;
|
use chrono::offset::TimeZone;
|
||||||
|
|
||||||
|
struct MockLocaleProvider {
|
||||||
|
locale: String,
|
||||||
|
}
|
||||||
|
impl LocaleProvider for MockLocaleProvider {
|
||||||
|
fn get_system_locale(&self) -> String {
|
||||||
|
self.locale.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl MockLocaleProvider {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
locale: "en-US".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_locale(locale: String) -> Self {
|
||||||
|
Self { locale }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn date_formatted_correctly() {
|
fn date_formatted_correctly() {
|
||||||
let mut extension = DateExtension::new();
|
let locale_provider = MockLocaleProvider::new();
|
||||||
|
let mut extension = DateExtension::new(&locale_provider);
|
||||||
extension.fixed_date = Some(Local.ymd(2014, 7, 8).and_hms(9, 10, 11));
|
extension.fixed_date = Some(Local.ymd(2014, 7, 8).and_hms(9, 10, 11));
|
||||||
|
|
||||||
let param = vec![("format".to_string(), Value::String("%H:%M:%S".to_string()))]
|
let param = vec![("format".to_string(), Value::String("%H:%M:%S".to_string()))]
|
||||||
|
@ -98,7 +465,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn offset_works_correctly() {
|
fn offset_works_correctly() {
|
||||||
let mut extension = DateExtension::new();
|
let locale_provider = MockLocaleProvider::new();
|
||||||
|
let mut extension = DateExtension::new(&locale_provider);
|
||||||
extension.fixed_date = Some(Local.ymd(2014, 7, 8).and_hms(9, 10, 11));
|
extension.fixed_date = Some(Local.ymd(2014, 7, 8).and_hms(9, 10, 11));
|
||||||
|
|
||||||
let param = vec![
|
let param = vec![
|
||||||
|
@ -115,4 +483,61 @@ mod tests {
|
||||||
ExtensionOutput::Single("10:10:11".to_string())
|
ExtensionOutput::Single("10:10:11".to_string())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_locale_works_correctly() {
|
||||||
|
let locale_provider = MockLocaleProvider::new_with_locale("it-IT".to_string());
|
||||||
|
let mut extension = DateExtension::new(&locale_provider);
|
||||||
|
extension.fixed_date = Some(Local.ymd(2014, 7, 8).and_hms(9, 10, 11));
|
||||||
|
|
||||||
|
let param = vec![("format".to_string(), Value::String("%A".to_string()))]
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Params>();
|
||||||
|
assert_eq!(
|
||||||
|
extension
|
||||||
|
.calculate(&Default::default(), &Default::default(), ¶m)
|
||||||
|
.into_success()
|
||||||
|
.unwrap(),
|
||||||
|
ExtensionOutput::Single("martedì".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_locale_should_default_to_en_us() {
|
||||||
|
let locale_provider = MockLocaleProvider::new_with_locale("invalid".to_string());
|
||||||
|
let mut extension = DateExtension::new(&locale_provider);
|
||||||
|
extension.fixed_date = Some(Local.ymd(2014, 7, 8).and_hms(9, 10, 11));
|
||||||
|
|
||||||
|
let param = vec![("format".to_string(), Value::String("%A".to_string()))]
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Params>();
|
||||||
|
assert_eq!(
|
||||||
|
extension
|
||||||
|
.calculate(&Default::default(), &Default::default(), ¶m)
|
||||||
|
.into_success()
|
||||||
|
.unwrap(),
|
||||||
|
ExtensionOutput::Single("Tuesday".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn override_locale() {
|
||||||
|
let locale_provider = MockLocaleProvider::new();
|
||||||
|
let mut extension = DateExtension::new(&locale_provider);
|
||||||
|
extension.fixed_date = Some(Local.ymd(2014, 7, 8).and_hms(9, 10, 11));
|
||||||
|
|
||||||
|
let param = vec![
|
||||||
|
("format".to_string(), Value::String("%A".to_string())),
|
||||||
|
("locale".to_string(), Value::String("it-IT".to_string())),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Params>();
|
||||||
|
assert_eq!(
|
||||||
|
extension
|
||||||
|
.calculate(&Default::default(), &Default::default(), ¶m)
|
||||||
|
.into_success()
|
||||||
|
.unwrap(),
|
||||||
|
ExtensionOutput::Single("martedì".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user