common-stdx 0.1.15

extension for the std lib, for things i commonly reuse
Documentation
use num_traits::Zero;
use serde::{Deserialize, Serialize};
use std::ops::{Add, Mul, Neg, Sub};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Point<T> {
    pub x: T,
    pub y: T,
}

impl<T> Point<T> {
    pub fn new(x: T, y: T) -> Self {
        Point { x, y }
    }
}

impl<T> From<(T, T)> for Point<T> {
    fn from((x, y): (T, T)) -> Self {
        Point { x, y }
    }
}

impl<T> Point<T>
where
    T: Copy + Zero + PartialEq,
{
    pub fn zero() -> Self {
        Point {
            x: T::zero(),
            y: T::zero(),
        }
    }

    pub fn is_zero(&self) -> bool {
        self.x == T::zero() && self.y == T::zero()
    }
}

impl<T> Add for Point<T>
where
    T: Add<Output = T> + Copy,
{
    type Output = Point<T>;
    fn add(self, rhs: Point<T>) -> Self::Output {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

impl<T> Sub for Point<T>
where
    T: Sub<Output = T> + Copy,
{
    type Output = Point<T>;
    fn sub(self, rhs: Point<T>) -> Self::Output {
        Point {
            x: self.x - rhs.x,
            y: self.y - rhs.y,
        }
    }
}

impl<T> Mul<T> for Point<T>
where
    T: Mul<Output = T> + Copy,
{
    type Output = Point<T>;
    fn mul(self, rhs: T) -> Self::Output {
        Point {
            x: self.x * rhs,
            y: self.y * rhs,
        }
    }
}

impl<T> Neg for Point<T>
where
    T: Neg<Output = T> + Copy,
{
    type Output = Point<T>;
    fn neg(self) -> Self::Output {
        Point {
            x: -self.x,
            y: -self.y,
        }
    }
}

impl<T> Point<T>
where
    T: Copy + Mul<Output = T> + Add<Output = T>,
{
    pub fn dot(self, other: Point<T>) -> T {
        self.x * other.x + self.y * other.y
    }
}

#[cfg(feature = "float")]
impl<T> Point<T>
where
    T: Copy + Sub<Output = T> + Into<f64>,
{
    pub fn distance(self, other: Point<T>) -> f64 {
        let dx: f64 = (self.x - other.x).into();
        let dy: f64 = (self.y - other.y).into();
        (dx * dx + dy * dy).sqrt()
    }

    pub fn magnitude(self) -> f64 {
        let x: f64 = self.x.into();
        let y: f64 = self.y.into();
        (x * x + y * y).sqrt()
    }
}