From 1d3a18609252b92fcba465f33fab4709f8bc3b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C3=B6lfchen?= Date: Wed, 28 Aug 2024 08:29:52 +0000 Subject: [PATCH] fix: make formattime follow system locale (#1177) closes #869 Co-authored-by: CrumblyLiquid --- Cargo.lock | 8 ++++++++ crates/eww_shared_util/Cargo.toml | 1 + crates/eww_shared_util/src/lib.rs | 2 ++ crates/eww_shared_util/src/locale.rs | 14 ++++++++++++++ crates/simplexpr/Cargo.toml | 2 +- crates/simplexpr/src/eval.rs | 10 +++++++--- 6 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 crates/eww_shared_util/src/locale.rs diff --git a/Cargo.lock b/Cargo.lock index b44e5a0e8..6b5b3c90b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -485,6 +485,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "pure-rust-locales", "wasm-bindgen", "windows-targets 0.52.6", ] @@ -975,6 +976,7 @@ dependencies = [ name = "eww_shared_util" version = "0.1.0" dependencies = [ + "chrono", "derive_more", "ref-cast", "serde", @@ -2238,6 +2240,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pure-rust-locales" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a" + [[package]] name = "quote" version = "1.0.37" diff --git a/crates/eww_shared_util/Cargo.toml b/crates/eww_shared_util/Cargo.toml index 24a9108ca..45d26dcdf 100644 --- a/crates/eww_shared_util/Cargo.toml +++ b/crates/eww_shared_util/Cargo.toml @@ -12,3 +12,4 @@ homepage = "https://github.com/elkowar/eww" serde.workspace = true derive_more.workspace = true ref-cast.workspace = true +chrono = { workspace = true, features = ["unstable-locales"] } diff --git a/crates/eww_shared_util/src/lib.rs b/crates/eww_shared_util/src/lib.rs index 299f994b7..716112088 100644 --- a/crates/eww_shared_util/src/lib.rs +++ b/crates/eww_shared_util/src/lib.rs @@ -1,6 +1,8 @@ +pub mod locale; pub mod span; pub mod wrappers; +pub use locale::*; pub use span::*; pub use wrappers::*; diff --git a/crates/eww_shared_util/src/locale.rs b/crates/eww_shared_util/src/locale.rs new file mode 100644 index 000000000..028e84b2b --- /dev/null +++ b/crates/eww_shared_util/src/locale.rs @@ -0,0 +1,14 @@ +use chrono::Locale; +use std::env::var; + +/// Returns the `Locale` enum based on the `LC_TIME` environment variable. +/// If the environment variable is not defined or is malformed use the POSIX locale. +pub fn get_locale() -> Locale { + let locale_string: String = + var("LC_TIME").map_or_else(|_| "C".to_string(), |v| v.split(".").next().unwrap_or("C").to_string()); + + match (&*locale_string).try_into() { + Ok(x) => x, + Err(_) => Locale::POSIX, + } +} diff --git a/crates/simplexpr/Cargo.toml b/crates/simplexpr/Cargo.toml index 099d5ddc7..2b94ae9e8 100644 --- a/crates/simplexpr/Cargo.toml +++ b/crates/simplexpr/Cargo.toml @@ -16,7 +16,7 @@ eww_shared_util.workspace = true cached.workspace = true chrono-tz.workspace = true -chrono.workspace = true +chrono = { workspace = true, features = ["unstable-locales"] } itertools.workspace = true jaq-core.workspace = true jaq-parse.workspace = true diff --git a/crates/simplexpr/src/eval.rs b/crates/simplexpr/src/eval.rs index f426b7995..6325782d5 100644 --- a/crates/simplexpr/src/eval.rs +++ b/crates/simplexpr/src/eval.rs @@ -7,7 +7,7 @@ use crate::{ ast::{AccessType, BinOp, SimplExpr, UnaryOp}, dynval::{ConversionError, DynVal}, }; -use eww_shared_util::{Span, Spanned, VarName}; +use eww_shared_util::{get_locale, Span, Spanned, VarName}; use std::{ collections::HashMap, convert::{Infallible, TryFrom, TryInto}, @@ -467,12 +467,16 @@ fn call_expr_function(name: &str, args: Vec) -> Result t.format(&format.as_string()?).to_string(), + LocalResult::Single(t) | LocalResult::Ambiguous(t, _) => { + t.format_localized(&format.as_string()?, get_locale()).to_string() + } LocalResult::None => return Err(EvalError::ChronoError("Invalid UNIX timestamp".to_string())), })) } [timestamp, format] => Ok(DynVal::from(match Local.timestamp_opt(timestamp.as_i64()?, 0) { - LocalResult::Single(t) | LocalResult::Ambiguous(t, _) => t.format(&format.as_string()?).to_string(), + LocalResult::Single(t) | LocalResult::Ambiguous(t, _) => { + t.format_localized(&format.as_string()?, get_locale()).to_string() + } LocalResult::None => return Err(EvalError::ChronoError("Invalid UNIX timestamp".to_string())), })), _ => Err(EvalError::WrongArgCount(name.to_string())),