use std::env;
use std::sync::{OnceLock, RwLock};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Glyphs {
pub ok: &'static str,
pub err: &'static str,
pub info: &'static str,
pub warn: &'static str,
pub spinner: &'static [&'static str],
pub bar_filled: &'static str,
pub bar_empty: &'static str,
pub rail: &'static str,
pub phase_done: &'static str,
pub dash: &'static str,
pub h_line: &'static str,
pub tree_branch: &'static str,
pub tree_last: &'static str,
pub tree_pipe: &'static str,
}
pub static UNICODE_GLYPHS: Glyphs = Glyphs {
ok: "\u{2713}",
err: "\u{2717}",
info: "\u{2139}",
warn: "\u{26a0}",
spinner: &[
"\u{00b7}", "\u{2722}", "\u{2733}", "\u{2736}", "\u{273b}", "\u{273d}",
],
bar_filled: "\u{2588}",
bar_empty: "\u{2591}",
rail: "\u{2502}",
phase_done: "\u{25c6}",
dash: "\u{2014}",
h_line: "\u{2500}",
tree_branch: "\u{251c}\u{2500}\u{2500} ",
tree_last: "\u{2514}\u{2500}\u{2500} ",
tree_pipe: "\u{2502} ",
};
pub static ASCII_GLYPHS: Glyphs = Glyphs {
ok: "[OK]",
err: "[ERR]",
info: "[i]",
warn: "[!]",
spinner: &[".", "*", "+", "x", "o", "O"],
bar_filled: "#",
bar_empty: "-",
rail: "|",
phase_done: "*",
dash: "-",
h_line: "-",
tree_branch: "|-- ",
tree_last: "`-- ",
tree_pipe: "| ",
};
static CACHED: OnceLock<RwLock<Option<Glyphs>>> = OnceLock::new();
static PLATFORM_OVERRIDE: OnceLock<RwLock<Option<&'static str>>> = OnceLock::new();
fn current_platform() -> &'static str {
let cell = PLATFORM_OVERRIDE.get_or_init(|| RwLock::new(None));
if let Some(platform) = *cell.read().expect("platform override poisoned") {
return platform;
}
if cfg!(windows) {
"win32"
} else if cfg!(target_os = "macos") {
"darwin"
} else if cfg!(target_os = "linux") {
"linux"
} else {
env::consts::OS
}
}
pub fn supports_unicode() -> bool {
if env::var("RUSTCODEGRAPH_ASCII").ok().as_deref() == Some("1") {
return false;
}
if env::var("RUSTCODEGRAPH_UNICODE").ok().as_deref() == Some("1") {
return true;
}
if current_platform() == "win32" {
return false;
}
env::var("TERM").ok().as_deref() != Some("linux")
}
pub fn get_glyphs() -> Glyphs {
let cell = CACHED.get_or_init(|| RwLock::new(None));
{
let cached = cell.read().expect("glyph cache poisoned");
if let Some(glyphs) = cached.clone() {
return glyphs;
}
}
let glyphs = if supports_unicode() {
UNICODE_GLYPHS.clone()
} else {
ASCII_GLYPHS.clone()
};
*cell.write().expect("glyph cache poisoned") = Some(glyphs.clone());
glyphs
}
pub fn reset_glyphs_cache() {
if let Some(cell) = CACHED.get() {
*cell.write().expect("glyph cache poisoned") = None;
}
}
#[doc(hidden)]
pub fn __set_platform_for_tests(platform: &'static str) {
let cell = PLATFORM_OVERRIDE.get_or_init(|| RwLock::new(None));
*cell.write().expect("platform override poisoned") = Some(platform);
}
#[doc(hidden)]
pub fn __reset_platform_for_tests() {
if let Some(cell) = PLATFORM_OVERRIDE.get() {
*cell.write().expect("platform override poisoned") = None;
}
}