bismuth 0.0.4

A 3D game world represented as cubes in an oct-tree that can be manipulated in real time.
Documentation
use nalgebra;
use num::Num;
use std::cmp::Ordering;
use std::convert::From;
use std::marker::PhantomData;
use std::ops;

use math::Clamp;

pub trait ClampedRange<T> {
    fn max_value() -> T;
    fn min_value() -> T;
}

#[derive(Clone, Copy)]
pub struct Clamped<T, R>(T, PhantomData<R>)
where
    T: Copy + Num + PartialOrd,
    R: ClampedRange<T>;

impl<T, R> Clamped<T, R>
where
    T: Copy + Num + PartialOrd,
    R: ClampedRange<T>,
{
    pub fn new(value: T) -> Self {
        Clamped(
            nalgebra::clamp(value, R::min_value(), R::max_value()),
            PhantomData,
        )
    }

    pub fn max_value() -> Self {
        Clamped(R::max_value(), PhantomData)
    }

    pub fn max_inner_value() -> T {
        R::max_value()
    }

    pub fn min_value() -> Self {
        Clamped(R::min_value(), PhantomData)
    }

    pub fn min_inner_value() -> T {
        R::min_value()
    }

    pub fn to_inner(&self) -> T {
        self.0
    }
}

impl<T, R> Clamp<Clamped<T, R>> for Clamped<T, R>
where
    T: Copy + Num + PartialOrd,
    R: ClampedRange<T> + Copy,
{
    fn clamp(&self, min: Self, max: Self) -> Self {
        nalgebra::clamp(*self, min, max)
    }
}

impl<T, R> From<T> for Clamped<T, R>
where
    T: Copy + Num + PartialOrd,
    R: ClampedRange<T>,
{
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

impl<T, R> Eq for Clamped<T, R>
where
    T: Copy + Eq + Num + PartialOrd,
    R: ClampedRange<T>,
{
}

impl<T, R> Ord for Clamped<T, R>
where
    T: Copy + Num + Ord + PartialOrd,
    R: ClampedRange<T>,
{
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }
}

impl<T, R> PartialEq for Clamped<T, R>
where
    T: Copy + Num + PartialEq + PartialOrd,
    R: ClampedRange<T>,
{
    fn eq(&self, other: &Self) -> bool {
        self.0.eq(&other.0)
    }
}

impl<T, R> PartialEq<T> for Clamped<T, R>
where
    T: Copy + Num + PartialEq + PartialOrd,
    R: ClampedRange<T>,
{
    fn eq(&self, other: &T) -> bool {
        self.0.eq(other)
    }
}

impl<T, R> PartialOrd for Clamped<T, R>
where
    T: Copy + Num + PartialOrd,
    R: ClampedRange<T>,
{
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
}

impl<T, R> PartialOrd<T> for Clamped<T, R>
where
    T: Copy + Num + PartialOrd,
    R: ClampedRange<T>,
{
    fn partial_cmp(&self, other: &T) -> Option<Ordering> {
        self.0.partial_cmp(other)
    }
}

impl<T, R> ops::Add for Clamped<T, R>
where
    T: ops::Add<Output = T> + Copy + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn add(self, other: Self) -> Self::Output {
        Self::new(self.0.add(other.0))
    }
}

impl<T, R> ops::Add<T> for Clamped<T, R>
where
    T: ops::Add<Output = T> + Copy + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn add(self, other: T) -> Self::Output {
        Self::new(self.0.add(other))
    }
}

impl<T, R> ops::Deref for Clamped<T, R>
where
    T: Copy + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T, R> ops::Div for Clamped<T, R>
where
    T: Copy + ops::Div<Output = T> + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn div(self, other: Self) -> Self::Output {
        Self::new(self.0.div(other.0))
    }
}

impl<T, R> ops::Div<T> for Clamped<T, R>
where
    T: Copy + ops::Div<Output = T> + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn div(self, other: T) -> Self::Output {
        Self::new(self.0.div(other))
    }
}

impl<T, R> ops::Mul for Clamped<T, R>
where
    T: Copy + ops::Mul<Output = T> + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn mul(self, other: Self) -> Self::Output {
        Self::new(self.0.mul(other.0))
    }
}

impl<T, R> ops::Mul<T> for Clamped<T, R>
where
    T: Copy + ops::Mul<Output = T> + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn mul(self, other: T) -> Self::Output {
        Self::new(self.0.mul(other))
    }
}

impl<T, R> ops::Neg for Clamped<T, R>
where
    T: Copy + ops::Neg<Output = T> + Num + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn neg(self) -> Self::Output {
        Self::new(self.0.neg())
    }
}

impl<T, R> ops::Sub for Clamped<T, R>
where
    T: Copy + Num + ops::Sub<Output = T> + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn sub(self, other: Self) -> Self::Output {
        Self::new(self.0.sub(other.0))
    }
}

impl<T, R> ops::Sub<T> for Clamped<T, R>
where
    T: Copy + Num + ops::Sub<Output = T> + PartialOrd,
    R: ClampedRange<T>,
{
    type Output = Self;

    fn sub(self, other: T) -> Self::Output {
        Self::new(self.0.sub(other))
    }
}