use educe::Educe;
use std::env::{self, VarError};
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub(crate) enum Status {
CheckPermissions,
DisableChecks,
}
impl Status {
pub(crate) fn disabled(self) -> bool {
self == Status::DisableChecks
}
}
pub const GLOBAL_DISABLE_VAR: &str = "FS_MISTRUST_DISABLE_PERMISSIONS_CHECKS";
#[derive(Clone, Debug, Educe, Eq, PartialEq)]
#[educe(Default)]
pub(crate) enum Disable {
OnUserEnvVar(String),
#[educe(Default)]
OnGlobalEnvVar,
Never,
}
#[allow(clippy::match_like_matches_macro)]
fn from_env_var_value(input: std::result::Result<String, VarError>) -> Option<Status> {
let mut s = match input {
Ok(s) => s,
Err(VarError::NotPresent) => return None,
Err(VarError::NotUnicode(_)) => return Some(Status::DisableChecks),
};
s.make_ascii_lowercase();
match s.as_ref() {
"" => None,
"0" | "no" | "never" | "false" | "n" => Some(Status::CheckPermissions),
_ => Some(Status::DisableChecks),
}
}
fn from_env_var(varname: &str) -> Option<Status> {
from_env_var_value(env::var(varname))
}
impl Disable {
pub(crate) fn should_disable_checks(&self) -> Status {
match self {
Disable::OnUserEnvVar(varname) => from_env_var(varname)
.or_else(|| from_env_var(GLOBAL_DISABLE_VAR))
.unwrap_or(Status::CheckPermissions),
Disable::OnGlobalEnvVar => {
from_env_var(GLOBAL_DISABLE_VAR).unwrap_or(Status::CheckPermissions)
}
Disable::Never => Status::CheckPermissions,
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn from_val() {
for word in ["yes", "1", "true", "certainly", "whatever"] {
assert_eq!(
from_env_var_value(Ok(word.into())),
Some(Status::DisableChecks)
);
}
for word in ["no", "0", "false", "NO", "Never", "n"] {
assert_eq!(
from_env_var_value(Ok(word.into())),
Some(Status::CheckPermissions)
);
}
assert_eq!(from_env_var_value(Ok("".into())), None);
assert_eq!(from_env_var_value(Err(VarError::NotPresent)), None);
assert_eq!(
from_env_var_value(Err(VarError::NotUnicode("".into()))),
Some(Status::DisableChecks)
);
}
}