Skip to main content

blz_core/
profile.rs

1use std::ffi::OsStr;
2use std::sync::OnceLock;
3
4/// Execution profile that influences default storage locations and other behavior.
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub enum AppProfile {
7    /// Standard release profile matching user-facing installations.
8    Default,
9    /// Developer profile with isolated storage intended for test builds.
10    Dev,
11}
12
13static PROFILE: OnceLock<AppProfile> = OnceLock::new();
14
15/// Override the inferred application profile (primarily used by alternative binaries).
16///
17/// Subsequent calls after the profile has been set are ignored to preserve initialization order.
18pub fn set(profile: AppProfile) {
19    let _ = PROFILE.set(profile);
20}
21
22/// Determine the active profile, defaulting to production unless overridden.
23#[must_use]
24pub fn current() -> AppProfile {
25    *PROFILE.get_or_init(detect_profile)
26}
27
28/// Returns the directory slug used for platform-specific config/data paths.
29#[must_use]
30pub fn app_dir_slug() -> &'static str {
31    match current() {
32        AppProfile::Default => "blz",
33        AppProfile::Dev => "blz-dev",
34    }
35}
36
37/// Returns the dot-directory slug used for non-XDG fallbacks.
38#[must_use]
39pub fn dot_dir_slug() -> &'static str {
40    match current() {
41        AppProfile::Default => ".blz",
42        AppProfile::Dev => ".blz-dev",
43    }
44}
45
46fn detect_profile() -> AppProfile {
47    if let Ok(value) = std::env::var("BLZ_PROFILE") {
48        if value.eq_ignore_ascii_case("dev") {
49            return AppProfile::Dev;
50        }
51    }
52
53    if let Ok(exe) = std::env::current_exe() {
54        if let Some(name) = exe.file_name().and_then(OsStr::to_str) {
55            if name.contains("blz-dev") {
56                return AppProfile::Dev;
57            }
58        }
59    }
60
61    AppProfile::Default
62}