use regex::bytes::RegexSet; #[derive(Clone, Copy, Debug)] pub enum Action { Allow, Challenge, Drop, } impl std::str::FromStr for Action { type Err = (); fn from_str(s: &str) -> Result { match s { "allow" | "Allow" => Ok(Self::Allow), "challenge" | "Challenge" => Ok(Self::Challenge), "drop" | "Drop" => Ok(Self::Drop), _ => Err(()), } } } impl Action { pub fn to_str(self) -> &'static str { match self { Action::Allow => "Allow", Action::Challenge => "Challenge", Action::Drop => "Drop", } } } #[derive(Clone, Debug)] pub struct Policy { // Will be used when we add log #[allow(unused)] pub name: String, pub first_line_regex: String, pub action: Action, } pub struct CompiledPolicies { pub first_line_regex_set: RegexSet, pub policies: &'static [Policy], } impl CompiledPolicies { pub fn new(policies: &'static [Policy]) -> Self { let mut first_line_regexes = Vec::new(); for policy in policies.iter() { first_line_regexes.push(&policy.first_line_regex); } CompiledPolicies { first_line_regex_set: RegexSet::new(&first_line_regexes).unwrap(), policies, } } pub fn evaluate(&self, first_line: &[u8]) -> Option<&Policy> { let matches = self.first_line_regex_set.matches(first_line); matches.into_iter().next().map(|i| &self.policies[i]) } }