vector-space 0.5.0

Generic vector space trait for compatibility across various libraries
Documentation
#![no_std]
#![deny(missing_docs)]
/*!
This crate contains traits for working with vector spaces.

You can also define some library in terms of these traits instead of using a specific vector math implementation, so the user can choose, which one to use, or simply add multiple vector math libraries which implement these traits yourself by using this library.
**/

use core::{
    cmp::PartialOrd,
    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
};
use num_traits::{Zero, real::Real};

/// This trait specifies some type to be a vector type.
/// It specifies the scalar type and is required for other vector types.
pub trait VectorSpace: Zero + PartialEq
where
    Self: Add<Output = Self>
        + Sub<Output = Self>
        + Mul<<Self as VectorSpace>::Scalar, Output = Self>
        + Div<<Self as VectorSpace>::Scalar, Output = Self>
        + Neg<Output = Self>,
{
    /// The scalar type of the vector space.
    type Scalar: Real + PartialOrd;
}

impl VectorSpace for f32 {
    type Scalar = Self;
}
impl VectorSpace for f64 {
    type Scalar = Self;
}

/// This trait is automatically implemented for vector spaces, which also implement assignment operations.
pub trait VectorSpaceAssign:
    VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
{
}
impl<T> VectorSpaceAssign for T where
    T: VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
{
}

/// Marker trait for affine spaces, types whose differences are vectors.
pub trait AffineSpace: Sub<Output = Self::Diff> + Sized {
    /// The difference type.
    type Diff: VectorSpace;
}

impl<T, D> AffineSpace for T
where
    T: Sub<Output = D>,
    D: VectorSpace,
{
    type Diff = D;
}

/// Linear interpolation of two points.
#[inline]
pub fn interpolate<T>(a: T, b: T, ratio: <T::Diff as VectorSpace>::Scalar) -> T
where
    T: Clone + AffineSpace + Add<T::Diff, Output = T>,
{
    a.clone() + (b - a) * ratio
}