#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct PatternPriority {
pub specificity_score: u32,
pub format_family: FormatFamily,
pub unix_timestamp_penalty: bool,
}
impl PatternPriority {
pub fn new(specificity_score: u32, format_family: FormatFamily) -> Self {
let unix_timestamp_penalty = matches!(format_family, FormatFamily::Unix);
Self {
specificity_score,
format_family,
unix_timestamp_penalty,
}
}
pub fn effective_score(&self) -> i32 {
let base_score = -i32::try_from(self.specificity_score).unwrap_or(0);
let family_modifier = match self.format_family {
FormatFamily::Structured => 0, FormatFamily::Application => 100,
FormatFamily::Regional => 200,
FormatFamily::Database => 300,
FormatFamily::Legacy => 400,
FormatFamily::Unix => 1000, };
let penalty = if self.unix_timestamp_penalty { 500 } else { 0 };
base_score + family_modifier + penalty
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum FormatFamily {
Structured, Application, Regional, Database, Legacy, Unix, }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn effective_score_unix_has_penalty() {
let p = PatternPriority::new(10, FormatFamily::Unix);
assert_eq!(p.effective_score(), -10 + 1000 + 500);
}
#[test]
fn effective_score_structured_highest_priority() {
let p = PatternPriority::new(90, FormatFamily::Structured);
assert_eq!(p.effective_score(), -90);
}
#[test]
fn effective_score_higher_specificity_wins() {
let high = PatternPriority::new(100, FormatFamily::Structured);
let low = PatternPriority::new(50, FormatFamily::Structured);
assert!(high.effective_score() < low.effective_score());
}
#[test]
fn effective_score_each_family() {
let structured = PatternPriority::new(10, FormatFamily::Structured).effective_score();
let application = PatternPriority::new(10, FormatFamily::Application).effective_score();
let regional = PatternPriority::new(10, FormatFamily::Regional).effective_score();
let database = PatternPriority::new(10, FormatFamily::Database).effective_score();
let legacy = PatternPriority::new(10, FormatFamily::Legacy).effective_score();
let unix = PatternPriority::new(10, FormatFamily::Unix).effective_score();
assert!(structured < application);
assert!(application < regional);
assert!(regional < database);
assert!(database < legacy);
assert!(legacy < unix);
}
}