use approx::{AbsDiffEq, RelativeEq, UlpsEq};

use crate::gaussian::Gaussian;

impl AbsDiffEq for Gaussian {
    type Epsilon = <f64 as AbsDiffEq>::Epsilon;

    fn default_epsilon() -> Self::Epsilon {
        f64::default_epsilon()
    }

    fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
        f64::abs_diff_eq(&self.mu(), &other.mu(), epsilon)
            && f64::abs_diff_eq(&self.sigma(), &other.sigma(), epsilon)
    }
}

impl RelativeEq for Gaussian {
    fn default_max_relative() -> Self::Epsilon {
        f64::default_max_relative()
    }

    fn relative_eq(
        &self,
        other: &Self,
        epsilon: Self::Epsilon,
        max_relative: Self::Epsilon,
    ) -> bool {
        f64::relative_eq(&self.mu(), &other.mu(), epsilon, max_relative)
            && f64::relative_eq(&self.sigma(), &other.sigma(), epsilon, max_relative)
    }
}

impl UlpsEq for Gaussian {
    fn default_max_ulps() -> u32 {
        f64::default_max_ulps()
    }

    fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
        f64::ulps_eq(&self.mu(), &other.mu(), epsilon, max_ulps)
            && f64::ulps_eq(&self.sigma(), &other.sigma(), epsilon, max_ulps)
    }
}
