use super::matched_ids::MatchedIds;
use super::matched_messages::MatchedMessages;
use crate::{CaseId, Store};
pub struct CaseMatch {
pub case: CaseId,
pub messages: MatchedIds,
}
impl CaseMatch {
pub fn new(case: CaseId, messages: MatchedIds) -> Self {
CaseMatch { case, messages }
}
pub fn len(&self) -> usize {
self.messages.len()
}
pub fn get_fairest(mut matches: Vec<CaseMatch>) -> Option<CaseMatch> {
let max_pattern_len = matches.iter().map(|m| m.len()).max()?;
let mut sorted_matches: Vec<_> = matches
.iter()
.enumerate()
.map(|(i, m)| (i, m.messages.sorted(max_pattern_len)))
.collect();
sorted_matches.sort_by(|(_, a), (_, b)| a.cmp(&b));
let fairest_match_index = *sorted_matches.first().map(|(i, _)| i)?;
Some(matches.swap_remove(fairest_match_index))
}
pub fn to_messages<M>(self, store: &mut Store<M>) -> MatchedMessages<M> {
let messages = self
.messages
.0
.into_iter()
.map(|id| store.remove(&id).unwrap())
.collect();
MatchedMessages {
case: self.case,
messages,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::*;
#[test]
fn test_get_fairest_prefers_older_messages() {
let case1 = CaseMatch::new(CaseId(1), MatchedIds(vec![id!(1), id!(5)]));
let case2 = CaseMatch::new(CaseId(2), MatchedIds(vec![id!(2), id!(3), id!(4), id!(5)]));
let result = CaseMatch::get_fairest(vec![case1, case2]).unwrap();
assert_eq!(CaseId(1), result.case);
}
#[test]
fn test_get_fairest_one_is_prefix() {
let case1 = CaseMatch::new(CaseId(1), MatchedIds(vec![id!(1), id!(2)]));
let case2 = CaseMatch::new(CaseId(2), MatchedIds(vec![id!(1), id!(2), id!(3)]));
let result = CaseMatch::get_fairest(vec![case1, case2]).unwrap();
assert_eq!(CaseId(2), result.case);
}
#[test]
fn test_get_fairest_same_messages_matched() {
let case1 = CaseMatch::new(CaseId(1), MatchedIds(vec![id!(1), id!(2), id!(3)]));
let case2 = CaseMatch::new(CaseId(2), MatchedIds(vec![id!(1), id!(2), id!(3)]));
let result = CaseMatch::get_fairest(vec![case1, case2]).unwrap();
assert_eq!(CaseId(1), result.case);
}
#[test]
fn test_get_fairest_prefers_older_messages_many_patterns() {
let case1 = CaseMatch::new(CaseId(1), MatchedIds(vec![id!(7), id!(5), id!(10)]));
let case2 = CaseMatch::new(CaseId(2), MatchedIds(vec![id!(1), id!(4), id!(10)]));
let case3 = CaseMatch::new(CaseId(3), MatchedIds(vec![id!(2), id!(3), id!(10)]));
let case4 = CaseMatch::new(CaseId(4), MatchedIds(vec![id!(10), id!(1), id!(5)]));
let result = CaseMatch::get_fairest(vec![case1, case2, case3, case4]).unwrap();
assert_eq!(CaseId(2), result.case);
}
#[test]
fn test_get_fairest_empty_list() {
let matches: Vec<CaseMatch> = vec![];
let result = CaseMatch::get_fairest(matches);
assert!(result.is_none());
}
}