use std::path::PathBuf;
pub fn format_cost(usd: f64) -> String {
if usd >= 1_000.0 {
format!("${:.1}k", usd / 1_000.0)
} else if usd >= 10.0 {
format!("${:.2}", usd)
} else if usd > 0.0 {
format!("${:.3}", usd)
} else {
"$0.00".into()
}
}
pub fn format_tokens(count: u64) -> String {
if count >= 1_000_000 {
format!("{:.1}M", count as f64 / 1_000_000.0)
} else if count >= 1_000 {
format!("{}k", count / 1_000)
} else {
count.to_string()
}
}
pub fn discover_jsonl_dirs() -> Vec<PathBuf> {
if let Ok(raw) = std::env::var("CLAUDE_CONFIG_DIR") {
return raw
.split(',')
.map(str::trim)
.filter(|s| !s.is_empty())
.map(|s| PathBuf::from(s).join("projects"))
.collect();
}
let Some(home) = dirs::home_dir() else {
return Vec::new();
};
[home.join(".claude"), home.join(".config").join("claude")]
.into_iter()
.map(|p| p.join("projects"))
.filter(|p| p.is_dir())
.collect()
}
pub fn project_name_from_cwd(cwd: &str) -> String {
PathBuf::from(cwd)
.file_name()
.map(|n| n.to_string_lossy().into_owned())
.filter(|s| !s.is_empty())
.unwrap_or_else(|| "(unknown)".into())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_cost_picks_unit_by_magnitude() {
assert_eq!(format_cost(0.0), "$0.00");
assert_eq!(format_cost(0.005), "$0.005");
assert_eq!(format_cost(2.50), "$2.500");
assert_eq!(format_cost(12.34), "$12.34");
assert_eq!(format_cost(1234.0), "$1.2k");
}
#[test]
fn format_tokens_uses_m_and_k_suffixes() {
assert_eq!(format_tokens(0), "0");
assert_eq!(format_tokens(42), "42");
assert_eq!(format_tokens(1_500), "1k");
assert_eq!(format_tokens(3_400_000), "3.4M");
}
#[test]
fn project_name_from_cwd_takes_last_component() {
assert_eq!(
project_name_from_cwd("/home/owner/.ghq/github.com/unhappychoice/splashboard"),
"splashboard"
);
}
#[test]
fn project_name_from_cwd_handles_empty_path() {
assert_eq!(project_name_from_cwd(""), "(unknown)");
}
#[test]
fn discover_jsonl_dirs_honours_env_override() {
let _lock = crate::paths::TEST_ENV_LOCK
.lock()
.unwrap_or_else(|e| e.into_inner());
let prev = std::env::var("CLAUDE_CONFIG_DIR").ok();
unsafe { std::env::set_var("CLAUDE_CONFIG_DIR", "/tmp/a, /tmp/b") };
let dirs = discover_jsonl_dirs();
assert_eq!(dirs.len(), 2);
assert!(dirs[0].ends_with("a/projects"));
assert!(dirs[1].ends_with("b/projects"));
match prev {
Some(v) => unsafe { std::env::set_var("CLAUDE_CONFIG_DIR", v) },
None => unsafe { std::env::remove_var("CLAUDE_CONFIG_DIR") },
}
}
}