hexglobe 0.1.3

Library to generate hexagonal tessellations of a sphere quickly and accurately.
Documentation
use std::fmt::{Debug, Formatter};
use std::ops::{Add, Deref, Div, Mul, Sub};

/// Helper struct which stores the denominator of a fraction within the type. Not strictly necessary but helps
/// tremendously with readability and maintainability. Implements passthroughs for various common (in this library)
/// arithmetic methods.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct ImplicitDenominator<T, const N: u32>(T);

impl<T, const N: u32> ImplicitDenominator<T, N> {
    /// Create a new fraction with denominator `N`.
    pub fn new(value: T) -> Self {
        Self(value)
    }
}

impl<T, const N: u32> Deref for ImplicitDenominator<T, N> {
    type Target = T;
    
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T, const N: u32> ImplicitDenominator<T, N> {
    pub const fn wrap(v: T) -> Self {
        Self(v)
    }
    
    pub const fn inner(&self) -> T where T: Copy {
        self.0
    }
}

impl<T, const N: u32> Debug for ImplicitDenominator<T, N> where
    T : Debug {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}/{:?}", self.0, N)
    }
}

impl<T, U, const N: u32> Add<ImplicitDenominator<U, N>> for ImplicitDenominator<T, N> where
    T : Add<U> {
    type Output = ImplicitDenominator<<T as Add<U>>::Output, N>;
    
    fn add(self, rhs: ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0 + rhs.0)
    }
}

impl<'a, T, U, const N: u32> Add<&'a ImplicitDenominator<U, N>> for ImplicitDenominator<T, N> where
    T : Add<U>,
    U : Clone {
    type Output = ImplicitDenominator<<T as Add<U>>::Output, N>;
    
    fn add(self, rhs: &'a ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0 + rhs.0.clone())
    }
}

impl<'a, T, U, const N: u32> Add<ImplicitDenominator<U, N>> for &'a ImplicitDenominator<T, N> where
    T : Add<U> + Clone {
    type Output = ImplicitDenominator<<T as Add<U>>::Output, N>;
    
    fn add(self, rhs: ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0.clone() + rhs.0)
    }
}

impl<'a, 'b, T, U, const N: u32> Add<&'a ImplicitDenominator<U, N>> for &'b ImplicitDenominator<T, N> where
    T : Add<U> + Clone,
    U : Clone {
    type Output = ImplicitDenominator<<T as Add<U>>::Output, N>;
    
    fn add(self, rhs: &'a ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0.clone() + rhs.0.clone())
    }
}

impl<T, U, const N: u32> Sub<ImplicitDenominator<U, N>> for ImplicitDenominator<T, N> where
    T : Sub<U> {
    type Output = ImplicitDenominator<<T as Sub<U>>::Output, N>;
    
    fn sub(self, rhs: ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0 - rhs.0)
    }
}

impl<'a, T, U, const N: u32> Sub<&'a ImplicitDenominator<U, N>> for ImplicitDenominator<T, N> where
    T : Sub<U>,
    U : Clone {
    type Output = ImplicitDenominator<<T as Sub<U>>::Output, N>;
    
    fn sub(self, rhs: &'a ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0 - rhs.0.clone())
    }
}

impl<'a, T, U, const N: u32> Sub<ImplicitDenominator<U, N>> for &'a ImplicitDenominator<T, N> where
    T : Sub<U> + Clone {
    type Output = ImplicitDenominator<<T as Sub<U>>::Output, N>;
    
    fn sub(self, rhs: ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0.clone() - rhs.0)
    }
}

impl<'a, 'b, T, U, const N: u32> Sub<&'a ImplicitDenominator<U, N>> for &'b ImplicitDenominator<T, N> where
    T : Sub<U> + Clone,
    U : Clone {
    type Output = ImplicitDenominator<<T as Sub<U>>::Output, N>;
    
    fn sub(self, rhs: &'a ImplicitDenominator<U, N>) -> Self::Output {
        ImplicitDenominator(self.0.clone() - rhs.0.clone())
    }
}

impl<T, U, const N: u32> Mul<U> for ImplicitDenominator<T, N> where
    T : Mul<U> {
    type Output = ImplicitDenominator<<T as Mul<U>>::Output, N>;
    
    fn mul(self, rhs: U) -> Self::Output {
        ImplicitDenominator(self.0 * rhs)
    }
}

impl<'a, T, U, const N: u32> Mul<U> for &'a ImplicitDenominator<T, N> where
    T : Mul<U> + Clone {
    type Output = ImplicitDenominator<<T as Mul<U>>::Output, N>;
    
    fn mul(self, rhs: U) -> Self::Output {
        ImplicitDenominator(self.0.clone() * rhs)
    }
}

impl<T, U, const N: u32> Div<U> for ImplicitDenominator<T, N> where
    T : Div<U> {
    type Output = ImplicitDenominator<<T as Div<U>>::Output, N>;
    
    fn div(self, rhs: U) -> Self::Output {
        ImplicitDenominator(self.0 / rhs)
    }
}