use super::PathValidator;
use std::cell::RefCell;
thread_local! {
static FILESYSTEM_VALIDATOR: RefCell<Option<PathValidator>> = const { RefCell::new(None) };
}
pub fn set_filesystem_validator(validator: Option<PathValidator>) {
FILESYSTEM_VALIDATOR.with(|v| *v.borrow_mut() = validator);
}
pub fn get_filesystem_validator() -> Option<PathValidator> {
FILESYSTEM_VALIDATOR.with(|v| v.borrow().clone())
}
pub struct ScopedValidator {
_private: (),
}
impl ScopedValidator {
pub fn set(validator: PathValidator) -> Self {
set_filesystem_validator(Some(validator));
Self { _private: () }
}
}
impl Drop for ScopedValidator {
fn drop(&mut self) {
set_filesystem_validator(None);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validator_context() {
let validator = PathValidator::with_root_dir(std::path::PathBuf::from("/safe"));
set_filesystem_validator(Some(validator.clone()));
let retrieved = get_filesystem_validator().unwrap();
assert_eq!(
retrieved.restriction().root_dir,
validator.restriction().root_dir
);
set_filesystem_validator(None);
assert!(get_filesystem_validator().is_none());
}
#[test]
fn test_scoped_validator() {
assert!(get_filesystem_validator().is_none());
{
let validator = PathValidator::with_root_dir(std::path::PathBuf::from("/safe"));
let _scope = ScopedValidator::set(validator);
assert!(get_filesystem_validator().is_some());
}
assert!(get_filesystem_validator().is_none());
}
}