use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub};
pub trait Coordinate:
Copy
+ Clone
+ PartialOrd
+ PartialEq
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Self, Output = Self>
+ Div<Self, Output = Self>
+ AddAssign
+ Neg<Output = Self>
{
fn zero() -> Self;
fn one() -> Self;
fn to_float(&self) -> f64;
fn from_float(value: f64) -> Self;
fn abs_diff(&self, other: &Self) -> Self;
fn is_sign_negative(&self) -> bool;
fn average(&self, other: &Self) -> Self;
}
impl Coordinate for f64 {
fn zero() -> Self {
0.0
}
fn one() -> Self {
1.0
}
fn to_float(&self) -> f64 {
*self
}
fn from_float(value: f64) -> Self {
value
}
fn abs_diff(&self, other: &Self) -> Self {
(self - other).abs()
}
fn is_sign_negative(&self) -> bool {
*self < Self::zero()
}
fn average(&self, other: &Self) -> Self {
(self + other) / 2.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_f64_coordinate() {
let a: f64 = 2.5;
let b: f64 = -1.5;
assert_eq!(f64::zero(), 0.0);
assert_eq!(f64::one(), 1.0);
assert_eq!(a.to_float(), 2.5);
assert_eq!(f64::from_float(3.14), 3.14);
assert_eq!(a.abs_diff(&b), 4.0);
assert!(!a.is_sign_negative());
assert!(b.is_sign_negative());
assert_eq!(a.average(&b), 0.5);
}
}