use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use uuid::Uuid;
use khive_score::DeterministicScore;
use super::has_id::HasId;
#[derive(Debug, Clone, Copy)]
pub struct ScoredEntry<T> {
candidate: T,
score: f64,
id: Uuid,
index: usize,
det_score: DeterministicScore,
}
impl<T: HasId> ScoredEntry<T> {
#[inline]
pub fn new(candidate: T, score: f64, index: usize) -> Self {
let id = candidate.id();
let det_score = DeterministicScore::from_f64(score);
Self {
candidate,
score,
id,
index,
det_score,
}
}
#[inline]
pub fn candidate(&self) -> &T {
&self.candidate
}
#[inline]
pub fn into_candidate(self) -> T {
self.candidate
}
#[inline]
pub fn score(&self) -> f64 {
self.score
}
#[inline]
pub fn id(&self) -> Uuid {
self.id
}
#[inline]
pub fn index(&self) -> usize {
self.index
}
#[inline]
pub fn det_score(&self) -> DeterministicScore {
self.det_score
}
}
impl<T> Eq for ScoredEntry<T> {}
impl<T> PartialEq for ScoredEntry<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.det_score == other.det_score && self.id == other.id
}
}
impl<T> Ord for ScoredEntry<T> {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.det_score
.cmp(&other.det_score)
.then_with(|| other.id.cmp(&self.id))
}
}
impl<T> PartialOrd for ScoredEntry<T> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T> Hash for ScoredEntry<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.det_score.hash(state);
self.id.hash(state);
}
}
#[cfg(test)]
#[path = "scored_entry_tests.rs"]
mod tests;