pub fn numeric(s: &str) -> bool {
!s.is_empty() && s.bytes().all(|b| b.is_ascii_digit())
}
pub fn alpha(s: &str) -> bool {
!s.is_empty() && s.bytes().all(|b| b.is_ascii_alphabetic())
}
pub fn alphanumeric(s: &str) -> bool {
!s.is_empty() && s.bytes().all(|b| b.is_ascii_alphanumeric())
}
pub fn uuid_like(s: &str) -> bool {
let groups = [8, 4, 4, 4, 12];
let parts: Vec<&str> = s.split('-').collect();
parts.len() == groups.len()
&& parts
.iter()
.zip(groups)
.all(|(p, n)| p.len() == n && p.bytes().all(|b| b.is_ascii_hexdigit()))
}
pub type Validator = fn(&str) -> bool;
#[derive(Default)]
pub struct Constraints {
rules: Vec<(String, Validator)>,
}
impl Constraints {
pub fn new() -> Self {
Self::default()
}
pub fn param(mut self, name: &str, validator: Validator) -> Self {
self.rules.push((name.to_string(), validator));
self
}
pub fn matches(&self, params: &[(&str, &str)]) -> bool {
self.rules.iter().all(|(name, validator)| {
params
.iter()
.find(|(k, _)| k == name)
.map(|(_, v)| validator(v))
.unwrap_or(false)
})
}
}