44 lines
1.5 KiB
Rust
44 lines
1.5 KiB
Rust
//! Explicit data-directory isolation for portable use and native release QA.
|
|||
|
|
//! Ordinary launches continue to use the operating system's app-data directory.
|
||
|
|
use std::{ffi::OsString, io, path::PathBuf};
|
||
|
|
|
||
|
|
pub fn resolve(default: PathBuf, override_path: Option<OsString>) -> io::Result<PathBuf> {
|
||
|
|
let Some(value) = override_path else {
|
||
|
|
return Ok(default);
|
||
|
|
};
|
||
|
|
let path = PathBuf::from(value);
|
||
|
|
if !path.is_absolute() || path.as_os_str().len() > 32768 {
|
||
|
|
return Err(io::Error::new(
|
||
|
|
io::ErrorKind::InvalidInput,
|
||
|
|
"SEARCHI_DATA_DIR must be an absolute bounded directory path",
|
||
|
|
));
|
||
|
|
}
|
||
|
|
Ok(path)
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(test)]
|
||
|
|
mod tests {
|
||
|
|
use super::*;
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn explicit_directory_isolates_settings_and_index_without_changing_default() {
|
||
|
|
let default = std::env::temp_dir().join("searchi-default");
|
||
|
|
let isolated = std::env::temp_dir().join("searchi-isolated");
|
||
|
|
assert_eq!(resolve(default.clone(), None).unwrap(), default);
|
||
|
|
assert_eq!(
|
||
|
|
resolve(default, Some(isolated.clone().into_os_string())).unwrap(),
|
||
|
|
isolated
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn invalid_override_is_rejected_without_falling_back_to_user_data() {
|
||
|
|
let default = std::env::temp_dir().join("searchi-default");
|
||
|
|
for value in [OsString::new(), OsString::from("relative/data")] {
|
||
|
|
assert_eq!(
|
||
|
|
resolve(default.clone(), Some(value)).unwrap_err().kind(),
|
||
|
|
io::ErrorKind::InvalidInput
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|