#![forbid(unsafe_code)]
pub enum SudoDefault {
Flag(bool),
Integer(OptTuple<i64>, fn(&str) -> Option<i64>),
Text(OptTuple<Option<&'static str>>),
List(&'static [&'static str]),
Enum(OptTuple<StrEnum<'static>>),
}
#[derive(Debug)]
pub struct OptTuple<T> {
pub default: T,
pub negated: Option<T>,
}
mod strenum;
pub use strenum::StrEnum;
mod settings_dsl;
use settings_dsl::*;
defaults! {
always_query_group_plugin = false
always_set_home = false
env_reset = true
mail_badpass = true
match_group_by_gid = false
use_pty = true
visiblepw = false
env_editor = true
passwd_tries = 3 [0..=1000]
secure_path = None (!= None)
verifypw = "all" (!= "never") [all, always, any, never]
timestamp_timeout = (15*60) (!= 0) {fractional_minutes}
env_keep = ["COLORS", "DISPLAY", "HOSTNAME", "KRB5CCNAME", "LS_COLORS", "PATH",
"PS1", "PS2", "XAUTHORITY", "XAUTHORIZATION", "XDG_CURRENT_DESKTOP"]
env_check = ["COLORTERM", "LANG", "LANGUAGE", "LC_*", "LINGUAS", "TERM", "TZ"]
env_delete = ["IFS", "CDPATH", "LOCALDOMAIN", "RES_OPTIONS", "HOSTALIASES",
"NLSPATH", "PATH_LOCALE", "LD_*", "_RLD*", "TERMINFO", "TERMINFO_DIRS",
"TERMPATH", "TERMCAP", "ENV", "BASH_ENV", "PS4", "GLOBIGNORE",
"BASHOPTS", "SHELLOPTS", "JAVA_TOOL_OPTIONS", "PERLIO_DEBUG",
"PERLLIB", "PERL5LIB", "PERL5OPT", "PERL5DB", "FPATH", "NULLCMD",
"READNULLCMD", "ZDOTDIR", "TMPPREFIX", "PYTHONHOME", "PYTHONPATH",
"PYTHONINSPECT", "PYTHONUSERBASE", "RUBYLIB", "RUBYOPT", "*=()*"]
}
fn fractional_minutes(input: &str) -> Option<i64> {
if input.contains('.') {
Some((input.parse::<f64>().ok()? * 60.0).floor() as i64)
} else {
Some(input.parse::<i64>().ok()? * 60)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn check() {
macro_rules! test {
($name:ident => $value:pat) => {
let Some(foo @ $value) = sudo_default(stringify!($name)) else {
unreachable!()
};
if let SudoDefault::Enum(OptTuple { default, negated }) = foo {
assert!(default
.possible_values
.iter()
.any(|x| *x as *const str == default.get()));
negated.map(|neg| assert!(neg.possible_values.contains(&neg.get())));
}
};
}
assert!(sudo_default("bla").is_none());
use SudoDefault::*;
test! { always_query_group_plugin => Flag(false) };
test! { always_set_home => Flag(false) };
test! { env_reset => Flag(true) };
test! { mail_badpass => Flag(true) };
test! { match_group_by_gid => Flag(false) };
test! { use_pty => Flag(true) };
test! { visiblepw => Flag(false) };
test! { env_editor => Flag(true) };
test! { passwd_tries => Integer(OptTuple { default: 3, negated: None }, _) };
test! { secure_path => Text(OptTuple { default: None, negated: Some(None) }) };
test! { env_keep => List(_) };
test! { env_check => List(["COLORTERM", "LANG", "LANGUAGE", "LC_*", "LINGUAS", "TERM", "TZ"]) };
test! { env_delete => List(_) };
test! { verifypw => Enum(OptTuple { default: StrEnum { value: "all", possible_values: [_, "always", "any", _] }, negated: Some(StrEnum { value: "never", .. }) }) };
let myenum = StrEnum::new("hello", &["hello", "goodbye"]).unwrap();
assert!(&myenum as &str == "hello");
}
}