use crate::skerror;
use crate::SKResult;
#[cfg(feature = "pybindings")]
use process_path::get_dylib_path;
use std::cell::OnceCell;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Mutex;
static DATADIR_SINGLETON: Mutex<OnceCell<Option<PathBuf>>> = Mutex::new(OnceCell::new());
pub fn testdirs() -> Vec<PathBuf> {
let mut testdirs: Vec<PathBuf> = Vec::new();
match std::env::var(&"SATKIT_DATA") {
Ok(val) => testdirs.push(Path::new(&val).to_path_buf()),
Err(_) => (),
}
#[cfg(feature = "pybindings")]
match get_dylib_path() {
Some(v) => {
testdirs.push(Path::new(&v).parent().unwrap().join("satkit-data"));
}
None => (),
}
match std::env::var(&"HOME") {
Ok(val) => {
let vstr = &String::from(val);
#[cfg(target_os = "macos")]
testdirs.push(
Path::new(vstr)
.join("Library")
.join("Application Support")
.join("satkit-data"),
);
testdirs.push(Path::new(vstr).join(".satkit-data"));
}
Err(_e) => (),
}
testdirs.push(Path::new(&"/usr/share/satkit-data").to_path_buf());
#[cfg(target_os = "macos")]
testdirs.push(Path::new(&"/Library/Application Support/satkit-data").to_path_buf());
testdirs
}
pub fn set_datadir(d: &PathBuf) -> SKResult<()> {
if !d.is_dir() {
return skerror!("Data directory does not exist");
}
let mut dd = DATADIR_SINGLETON.lock().unwrap();
dd.take();
match dd.set(Some(d.clone())) {
Ok(_) => Ok(()),
Err(_) => return skerror!("Could not set data directory"),
}
}
pub fn datadir() -> SKResult<PathBuf> {
let dd = DATADIR_SINGLETON.lock().unwrap();
let res = dd.get_or_init(|| {
let td: Vec<PathBuf> = testdirs();
for ref dir in td.clone() {
let p = PathBuf::from(&dir).join("tab5.2a.txt");
if p.is_file() {
return Some(dir.to_path_buf().clone());
}
}
for ref dir in td.clone() {
if dir.is_dir() {
if !dir.metadata().unwrap().permissions().readonly() {
return Some(dir.to_path_buf().clone());
}
}
}
for ref dir in td.clone() {
match std::fs::create_dir_all(dir) {
Ok(()) => return Some(dir.to_path_buf().clone()),
Err(_) => {}
}
}
None
});
match res.as_ref() {
Some(v) => Ok(v.clone()),
None => skerror!("Could not find valid writeable data directory"),
}
}
pub fn data_found() -> bool {
match datadir() {
Ok(d) => {
let p = PathBuf::from(&d).join("tab5.2a.txt");
if p.is_file() {
true
} else {
false
}
}
Err(_) => false,
}
}
#[cfg(test)]
mod tests {
#[test]
fn datadir() {
use crate::utils::datadir;
let d = datadir::datadir();
println!("d = {:?}", d.as_ref().unwrap());
assert_eq!(d.is_err(), false);
}
}