1use std::path::{Path, PathBuf};
4
5const CHECKOUT_MARKERS: [&str; 2] = ["pnpm-workspace.yaml", "contracts/src/ParalockHTLC.sol"];
7
8pub fn find_checkout(start: &Path) -> Option<PathBuf> {
11 start.ancestors().find(|dir| CHECKOUT_MARKERS.iter().all(|marker| dir.join(marker).exists())).map(Path::to_path_buf)
12}
13
14pub fn home_dir() -> Option<PathBuf> {
16 let var = if cfg!(windows) { "USERPROFILE" } else { "HOME" };
17 std::env::var_os(var).filter(|v| !v.is_empty()).map(PathBuf::from)
18}
19
20pub fn state_dir(cwd: &Path, paralock_home: Option<&str>) -> PathBuf {
26 if let Some(checkout) = find_checkout(cwd) {
27 return checkout.join(".paralock");
28 }
29 match paralock_home.map(str::trim).filter(|h| !h.is_empty()) {
30 Some(home) => cwd.join(home),
31 None => home_dir().unwrap_or_else(|| cwd.to_path_buf()).join(".paralock"),
32 }
33}
34
35pub fn current_state_dir() -> PathBuf {
37 let cwd = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
38 state_dir(&cwd, std::env::var("PARALOCK_HOME").ok().as_deref())
39}
40
41pub fn resolve_path(path: &str, base: &Path) -> PathBuf {
43 let expanded = match path.strip_prefix("~/") {
44 Some(rest) => home_dir().map_or_else(|| PathBuf::from(path), |home| home.join(rest)),
45 None if path == "~" => home_dir().unwrap_or_else(|| PathBuf::from(path)),
46 None => PathBuf::from(path),
47 };
48 if expanded.is_absolute() { expanded } else { base.join(expanded) }
49}