use std::hash::{Hash, Hasher};
use std::path::Path;
pub struct UblxNames {
pub pkg_name: &'static str,
pub pkg_name_plural: &'static str,
pub index_db_file_ext: &'static str,
pub local_config_visible_toml: &'static str,
pub local_config_hidden_toml: &'static str,
pub nefax_db: &'static str,
pub zahir_export_dir_name: &'static str,
pub lens_export_dir_name: &'static str,
}
impl Default for UblxNames {
fn default() -> Self {
Self::new()
}
}
impl UblxNames {
#[must_use]
pub const fn new() -> Self {
Self {
pkg_name: env!("CARGO_PKG_NAME"),
pkg_name_plural: "ubli",
index_db_file_ext: concat!(".", env!("CARGO_PKG_NAME")),
local_config_visible_toml: concat!(env!("CARGO_PKG_NAME"), ".toml"),
local_config_hidden_toml: concat!(".", env!("CARGO_PKG_NAME"), ".toml"),
nefax_db: ".nefaxer",
zahir_export_dir_name: concat!(env!("CARGO_PKG_NAME"), "-export"),
lens_export_dir_name: concat!(env!("CARGO_PKG_NAME"), "-lenses"),
}
}
}
pub const UBLX_NAMES: UblxNames = UblxNames::new();
const PATH_HASH_HEX_LEN: usize = 16;
#[must_use]
pub fn is_hex_hash16(s: &str) -> bool {
s.len() == PATH_HASH_HEX_LEN && s.chars().all(|c| c.is_ascii_hexdigit())
}
#[must_use]
pub fn hash_suffix_from_db_stem(stem: &str) -> Option<&str> {
let (_, rest) = stem.rsplit_once('_')?;
is_hex_hash16(rest).then_some(rest)
}
#[must_use]
pub fn path_to_hex(path: &Path) -> String {
let mut hasher = std::collections::hash_map::DefaultHasher::new();
path.to_string_lossy().hash(&mut hasher);
format!("{:016x}", hasher.finish())
}
pub(super) fn sanitize_name_for_fs(name: &str) -> String {
let mut out = String::with_capacity(name.len());
for ch in name.chars() {
if ch.is_ascii_alphanumeric() || ch == '-' || ch == '_' {
out.push(ch);
} else {
out.push('_');
}
}
let trimmed = out.trim_matches('_');
if trimmed.is_empty() {
"root".to_string()
} else {
trimmed.to_string()
}
}