use internal::TimeDelta;
use std;
use std::cmp::max;
use std::ops::*;
type RatingIntern = i64;
const RATING_PRECISION: RatingIntern = (1 << 32);
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Rating(RatingIntern);
impl std::fmt::Display for Rating {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0 as f64 / RATING_PRECISION as f64)
}
}
impl Rating {
pub fn zero() -> Rating {
Rating(0)
}
pub fn from_overlapping_spans(a: TimeDelta, b: TimeDelta) -> Rating {
let max: RatingIntern = max(a, b).into();
let x = RATING_PRECISION / max;
Rating(x as RatingIntern)
}
pub fn nosplit_bonus(unnormalized: f64) -> Rating {
Rating((RATING_PRECISION as f64 * unnormalized) as RatingIntern)
}
}
#[cfg(test)]
impl From<i64> for Rating {
fn from(f: i64) -> Rating {
Rating(f as RatingIntern)
}
}
impl Add for Rating {
type Output = Rating;
fn add(self, c: Rating) -> Rating {
Rating(self.0 + c.0)
}
}
impl Sub for Rating {
type Output = Rating;
fn sub(self, c: Rating) -> Rating {
Rating(self.0 - c.0)
}
}
impl AddAssign for Rating {
fn add_assign(&mut self, c: Rating) {
self.0 += c.0;
}
}
impl SubAssign for Rating {
fn sub_assign(&mut self, c: Rating) {
self.0 -= c.0;
}
}
impl std::iter::Sum for Rating {
fn sum<I>(iter: I) -> Rating
where
I: Iterator<Item = Rating>,
{
Rating(iter.map(|c| c.0).sum())
}
}
impl Mul<u64> for Rating {
type Output = Rating;
fn mul(self, rhs: u64) -> Rating {
Rating(self.0 * rhs as RatingIntern)
}
}
impl Mul<i64> for Rating {
type Output = Rating;
fn mul(self, rhs: i64) -> Rating {
Rating(self.0 * rhs as RatingIntern)
}
}
impl Div<Rating> for Rating {
type Output = i64;
fn div(self, rhs: Rating) -> i64 {
(self.0 / rhs.0) as i64
}
}
impl Neg for Rating {
type Output = Rating;
fn neg(self) -> Rating {
Rating(-self.0)
}
}