use std::sync::OnceLock;
#[derive(Debug, Clone, Copy)]
pub struct Glyphs {
pub selector: &'static str,
pub selector_blank: &'static str,
pub cursor: &'static str,
pub prompt: &'static str,
pub rule: &'static str,
pub ellipsis: &'static str,
pub times: &'static str,
pub collapsed: &'static str,
pub expanded: &'static str,
pub updown: &'static str,
pub updown_lr: &'static str,
}
const UNICODE: Glyphs = Glyphs {
selector: "▸ ",
selector_blank: " ",
cursor: "▏",
prompt: "› ",
rule: "│",
ellipsis: "…",
times: "×",
collapsed: "▸ ",
expanded: "▾ ",
updown: "↑↓",
updown_lr: "←→",
};
const ASCII: Glyphs = Glyphs {
selector: "> ",
selector_blank: " ",
cursor: "_",
prompt: "> ",
rule: "|",
ellipsis: "...",
times: "x",
collapsed: "+ ",
expanded: "- ",
updown: "Up/Dn",
updown_lr: "Lt/Rt",
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum UnicodeMode {
#[default]
Auto,
Always,
Never,
}
static GLYPHS: OnceLock<Glyphs> = OnceLock::new();
pub fn locale_is_utf8() -> bool {
for key in ["LC_ALL", "LC_CTYPE", "LANG"] {
if let Ok(value) = std::env::var(key) {
if value.is_empty() {
continue;
}
let lower = value.to_ascii_lowercase();
return lower.contains("utf-8") || lower.contains("utf8");
}
}
false
}
pub fn init(mode: UnicodeMode) {
let chosen = match mode {
UnicodeMode::Always => UNICODE,
UnicodeMode::Never => ASCII,
UnicodeMode::Auto => {
if locale_is_utf8() {
UNICODE
} else {
ASCII
}
}
};
let _ = GLYPHS.set(chosen);
}
pub fn get() -> &'static Glyphs {
GLYPHS.get_or_init(|| if locale_is_utf8() { UNICODE } else { ASCII })
}
pub fn unicode() -> &'static Glyphs {
&UNICODE
}
pub fn ascii() -> &'static Glyphs {
&ASCII
}