use conduwuit::Result; use regex::RegexSet; use ruma::api::appservice::Namespace; /// Compiled regular expressions for a namespace #[derive(Clone, Debug)] pub struct NamespaceRegex { pub exclusive: Option, pub non_exclusive: Option, } impl NamespaceRegex { /// Checks if this namespace has rights to a namespace #[inline] #[must_use] pub fn is_match(&self, heystack: &str) -> bool { if self.is_exclusive_match(heystack) { return true; } if let Some(non_exclusive) = &self.non_exclusive { if non_exclusive.is_match(heystack) { return true; } } false } /// Checks if this namespace has exlusive rights to a namespace #[inline] #[must_use] pub fn is_exclusive_match(&self, heystack: &str) -> bool { if let Some(exclusive) = &self.exclusive { if exclusive.is_match(heystack) { return true; } } false } } impl TryFrom> for NamespaceRegex { type Error = regex::Error; fn try_from(value: Vec) -> Result { let mut exclusive = Vec::with_capacity(value.len()); let mut non_exclusive = Vec::with_capacity(value.len()); for namespace in value { if namespace.exclusive { exclusive.push(namespace.regex); } else { non_exclusive.push(namespace.regex); } } Ok(Self { exclusive: if exclusive.is_empty() { None } else { Some(RegexSet::new(exclusive)?) }, non_exclusive: if non_exclusive.is_empty() { None } else { Some(RegexSet::new(non_exclusive)?) }, }) } }