1use anyhow::{anyhow, Context, Result};
4use std::path::PathBuf;
5
6const ENV_OVERRIDE: &str = "BROWSER_CONTROL_DATA_DIR";
7
8pub fn data_dir() -> Result<PathBuf> {
16 if let Some(v) = std::env::var_os(ENV_OVERRIDE) {
17 let p = PathBuf::from(v);
18 if p.as_os_str().is_empty() {
19 return Err(anyhow!("{} is set but empty", ENV_OVERRIDE));
20 }
21 return Ok(p);
22 }
23
24 let pd = directories::ProjectDirs::from("", "", "browser-control")
25 .ok_or_else(|| anyhow!("could not determine user data directory (no home dir found)"))?;
26 Ok(pd.data_dir().to_path_buf())
27}
28
29pub fn registry_db_path() -> Result<PathBuf> {
31 let dir = data_dir()?;
32 std::fs::create_dir_all(&dir)
33 .with_context(|| format!("creating data dir {}", dir.display()))?;
34 Ok(dir.join("registry.db"))
35}
36
37pub fn profiles_dir() -> Result<PathBuf> {
39 let dir = data_dir()?.join("profiles");
40 std::fs::create_dir_all(&dir)
41 .with_context(|| format!("creating profiles dir {}", dir.display()))?;
42 Ok(dir)
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn paths_work() {
51 let tmp = tempfile::TempDir::new().unwrap();
53 let tmp_path = tmp.path().to_path_buf();
54 std::env::set_var(ENV_OVERRIDE, &tmp_path);
57
58 assert_eq!(data_dir().unwrap(), tmp_path);
59
60 let db = registry_db_path().unwrap();
61 assert_eq!(db, tmp_path.join("registry.db"));
62 assert!(db.parent().unwrap().exists());
63 assert_eq!(db.file_name().unwrap(), "registry.db");
64
65 let pdir = profiles_dir().unwrap();
66 assert_eq!(pdir, tmp_path.join("profiles"));
67 assert!(pdir.is_dir());
68 assert_eq!(pdir.file_name().unwrap(), "profiles");
69
70 std::env::remove_var(ENV_OVERRIDE);
72 let d = data_dir().unwrap();
73 assert!(
74 d.ends_with("browser-control"),
75 "expected default data_dir to end with 'browser-control', got {}",
76 d.display()
77 );
78 }
79}