use std::path::PathBuf;
pub const PRODUCT_NAME: &str = "pithy";
pub const PRODUCT_BRAND: &str = "Pithy";
pub const ENV_PREFIX: &str = "PITHY";
pub const BUNDLE_NS: &str = "com.pithy";
pub const CONFIG_DIR_NAME: &str = ".pithy";
pub const REPO_URL: &str = "https://github.com/MikkoParkkola/pithy";
pub const ATTRIBUTION: &str = "Powered by Pithy(R) - https://github.com/MikkoParkkola/pithy";
#[must_use]
pub fn env_var_name(suffix: &str) -> String {
format!("{ENV_PREFIX}_{suffix}")
}
#[must_use]
pub fn config_dir() -> PathBuf {
std::env::var_os("HOME")
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("/tmp"))
.join(CONFIG_DIR_NAME)
}
#[must_use]
pub fn socket_path(name: &str) -> PathBuf {
PathBuf::from("/tmp").join(format!("{PRODUCT_NAME}-{name}.sock"))
}
#[must_use]
pub fn log_path(name: &str) -> PathBuf {
PathBuf::from("/tmp").join(format!("{PRODUCT_NAME}-{name}.jsonl"))
}
#[must_use]
pub fn bundle_id(component: &str) -> String {
format!("{BUNDLE_NS}.{component}")
}
#[must_use]
pub fn read_env(suffix: &str) -> Option<String> {
std::env::var(env_var_name(suffix))
.ok()
.or_else(|| std::env::var(format!("ULTRACOS_{suffix}")).ok())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn product_name_and_brand_agree_case_insensitive() {
assert_eq!(
PRODUCT_NAME.to_ascii_uppercase(),
PRODUCT_BRAND.to_ascii_uppercase(),
"PRODUCT_NAME={PRODUCT_NAME} and PRODUCT_BRAND={PRODUCT_BRAND} \
must differ only in casing; did a rename leave one behind?"
);
}
#[test]
fn env_prefix_matches_product_name_uppercase() {
assert_eq!(
ENV_PREFIX,
PRODUCT_NAME.to_ascii_uppercase(),
"ENV_PREFIX must be the uppercase form of PRODUCT_NAME"
);
}
#[test]
fn bundle_ns_uses_product_name() {
assert!(
BUNDLE_NS.ends_with(PRODUCT_NAME),
"BUNDLE_NS={BUNDLE_NS} must end with PRODUCT_NAME={PRODUCT_NAME}"
);
}
#[test]
fn config_dir_name_uses_product_name() {
assert_eq!(
CONFIG_DIR_NAME,
format!(".{PRODUCT_NAME}"),
"CONFIG_DIR_NAME must be the dot-prefixed PRODUCT_NAME"
);
}
#[test]
fn attribution_contains_brand() {
assert!(
ATTRIBUTION.contains(PRODUCT_BRAND),
"ATTRIBUTION must reference PRODUCT_BRAND={PRODUCT_BRAND}; \
got: {ATTRIBUTION}"
);
}
#[test]
fn attribution_contains_repo_url() {
assert!(
ATTRIBUTION.contains(REPO_URL),
"ATTRIBUTION must reference REPO_URL; got: {ATTRIBUTION}"
);
}
#[test]
fn env_var_name_joins_with_underscore() {
assert_eq!(
env_var_name("SHADOW_RATE"),
format!("{ENV_PREFIX}_SHADOW_RATE")
);
assert_eq!(env_var_name("BYPASS"), format!("{ENV_PREFIX}_BYPASS"));
}
#[test]
fn socket_path_uses_product_stem() {
let p = socket_path("shim");
assert_eq!(
p.to_string_lossy(),
format!("/tmp/{PRODUCT_NAME}-shim.sock")
);
}
#[test]
fn log_path_uses_product_stem() {
let p = log_path("shadow");
assert_eq!(
p.to_string_lossy(),
format!("/tmp/{PRODUCT_NAME}-shadow.jsonl")
);
}
#[test]
fn bundle_id_composes_from_ns_and_component() {
assert_eq!(bundle_id("shim"), format!("{BUNDLE_NS}.shim"));
assert_eq!(bundle_id("controller"), format!("{BUNDLE_NS}.controller"));
assert_eq!(bundle_id("embedder"), format!("{BUNDLE_NS}.embedder"));
}
#[test]
fn config_dir_joins_home_with_config_dir_name() {
std::env::set_var("HOME", "/tmp/branding-test-home");
let p = config_dir();
assert_eq!(
p.to_string_lossy(),
format!("/tmp/branding-test-home/{CONFIG_DIR_NAME}")
);
}
#[test]
fn read_env_falls_back_to_legacy_ultracos_prefix() {
let suffix = "BRANDING_LEGACY_FALLBACK_TEST";
let legacy_key = format!("ULTRACOS_{suffix}");
let current_key = env_var_name(suffix);
std::env::remove_var(&legacy_key);
std::env::remove_var(¤t_key);
std::env::set_var(&legacy_key, "legacy-hit");
let got = read_env(suffix);
std::env::remove_var(&legacy_key);
std::env::remove_var(¤t_key);
assert_eq!(got.as_deref(), Some("legacy-hit"));
}
#[test]
fn read_env_returns_none_when_unset() {
let key = "BRANDING_DEFINITELY_NOT_SET_XYZ";
std::env::remove_var(env_var_name(key));
std::env::remove_var(format!("ULTRACOS_{key}"));
assert_eq!(read_env(key), None);
}
}