1use super::errors::BridgeError;
7use std::path::PathBuf;
8
9#[cfg(unix)]
10use std::fs;
11
12#[cfg(windows)]
14const PYTHON_LIB_DIR: &str = "Lib";
15#[cfg(unix)]
16const PYTHON_LIB_DIR: &str = "lib";
17
18#[cfg(windows)]
20const PYTHON_BIN_DIR: &str = "Scripts";
21#[cfg(unix)]
22const PYTHON_BIN_DIR: &str = "bin";
23
24#[cfg(windows)]
26const PYTHON_EXE: &str = "python.exe";
27#[cfg(unix)]
28const PYTHON_EXE: &str = "python";
29
30pub fn resolve_site_package_path(venv_path: &PathBuf) -> Result<PathBuf, BridgeError> {
39 if !venv_path.is_dir() {
41 return Err(BridgeError::VenvNotFound(venv_path.to_path_buf()));
42 }
43
44 #[cfg(windows)]
45 {
46 let site_packages = venv_path.join(PYTHON_LIB_DIR).join("site-packages");
47
48 if !site_packages.is_dir() {
50 return Err(BridgeError::Initialization(format!(
51 "unable to locate package directory: {}",
52 site_packages.display()
53 )));
54 }
55 Ok(site_packages)
56 }
57
58 #[cfg(not(windows))]
59 {
60 let lib_dir = venv_path.join(PYTHON_LIB_DIR);
61
62 if !lib_dir.is_dir() {
63 return Err(BridgeError::Initialization(format!(
64 "unable to locate lib directory: {}",
65 lib_dir.display()
66 )));
67 }
68
69 let python_version_dir = fs::read_dir(&lib_dir)
70 .map_err(|e| {
71 BridgeError::Initialization(format!("Failed to read lib directory: {}", e))
72 })?
73 .filter_map(|e| e.ok())
74 .find(|e| e.file_name().to_string_lossy().starts_with("python"))
75 .ok_or_else(|| {
76 BridgeError::Initialization("No python3.X directory found in venv/lib".to_string())
77 })?;
78
79 let site_packages = python_version_dir.path().join("site-packages");
80
81 if !site_packages.is_dir() {
82 return Err(BridgeError::Initialization(format!(
83 "unable to locate package directory: {}",
84 site_packages.display()
85 )));
86 }
87
88 Ok(site_packages)
89 }
90}
91
92pub fn resolve_python_path(venv_path: &PathBuf) -> Result<PathBuf, BridgeError> {
93 if !venv_path.is_dir() {
95 return Err(BridgeError::VenvNotFound(venv_path.to_path_buf()));
96 }
97
98 let python_path = venv_path.join(PYTHON_BIN_DIR).join(PYTHON_EXE);
99 if !python_path.is_file() {
101 return Err(BridgeError::Initialization(format!(
102 "Path to python binary is not valid: {}",
103 python_path.display()
104 )));
105 }
106
107 return Ok(python_path);
108}