use crate::constants::env::system;
use std::sync::OnceLock;
static GRAPHEME_SEGMENTER: OnceLock<icu_segmenter::GraphemeClusterSegmenter> = OnceLock::new();
static WORD_SEGMENTER: OnceLock<icu_segmenter::WordSegmenter> = OnceLock::new();
static RTF_CACHE: std::sync::RwLock<std::collections::HashMap<String, once_cell::sync::Lazy<chrono::Locales>>>> =
std::sync::RwLock::new(std::collections::HashMap::new());
static CACHED_TIMEZONE: OnceLock<String> = OnceLock::new();
static CACHED_SYSTEM_LOCALE_LANGUAGE: OnceLock<Option<String>> = OnceLock::new();
pub fn get_grapheme_segmenter() -> &'static icu_segmenter::GraphemeClusterSegmenter {
GRAPHEME_SEGMENTER.get_or_init(icu_segmenter::GraphemeClusterSegmenter::new)
}
pub fn first_grapheme(text: &str) -> String {
if text.is_empty() {
return String::new();
}
let segmenter = get_grapheme_segmenter();
let graphemes: Vec<&str> = segmenter.segment(text).collect();
graphemes.first().map(|s| s.to_string()).unwrap_or_default()
}
pub fn last_grapheme(text: &str) -> String {
if text.is_empty() {
return String::new();
}
let segmenter = get_grapheme_segmenter();
let graphemes: Vec<&str> = segmenter.segment(text).collect();
graphemes.last().map(|s| s.to_string()).unwrap_or_default()
}
pub fn get_word_segmenter() -> &'static icu_segmenter::WordSegmenter {
WORD_SEGMENTER.get_or_init(icu_segmenter::WordSegmenter::new)
}
pub fn get_time_zone() -> &'static str {
CACHED_TIMEZONE.get_or_init(|| {
match chrono::Local::now().timezone().name().to_str() {
name if !name.is_empty() => name.to_string(),
_ => "UTC".to_string(),
}
})
}
pub fn get_system_locale_language() -> Option<&'static str> {
CACHED_SYSTEM_LOCALE_LANGUAGE.get_or_init(|| {
std::env::var(system::LANG)
.or_else(|_| std::env::var(system::LC_ALL))
.ok()
.and_then(|lang| {
lang.split('_').next().map(|s| s.to_string())
})
}).as_deref()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_first_grapheme() {
assert_eq!(first_grapheme("hello"), "h");
assert_eq!(first_grapheme(""), "");
}
#[test]
fn test_last_grapheme() {
assert_eq!(last_grapheme("hello"), "o");
assert_eq!(last_grapheme(""), "");
}
#[test]
fn test_get_time_zone() {
let tz = get_time_zone();
assert!(!tz.is_empty());
}
}