Created
July 16, 2018 08:27
-
-
Save zesterer/98b9710dc1062a3890805fb4382decef to your computer and use it in GitHub Desktop.
A few tests for coord
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(unused_imports)] | |
#![allow(dead_code)] | |
extern crate core; | |
use core::ops::{ | |
Add, Sub, Mul, Div, | |
AddAssign, SubAssign, MulAssign, DivAssign, | |
}; | |
use core::fmt; | |
// CORE TRAITS | |
trait VecItem: Copy + Clone {} | |
trait VecN { type Item: VecItem; } | |
impl<T: VecItem> VecN for Vec3<T> { type Item = T; } | |
// UNARY TO VECTOR OPERATORS | |
trait UnToVec<R: VecN>: VecN { | |
fn map<F: Fn(Self::Item) -> R::Item>(&self, f: F) -> R; | |
} | |
// UNARY TO SCALAR OPERATORS | |
trait UnToScal<R>: VecN { | |
fn fold<F: Fn(Self::Item, R) -> R>(&self, a: R, f: F) -> R; | |
fn fold_back<F: Fn(Self::Item, R) -> R>(&self, a: R, f: F) -> R; | |
fn apply_to<F: Fn(Self::Item, &mut R)>(&self, a: &mut R, f: F); | |
} | |
// BINARY TO VECTOR OPERATORS | |
trait BinToVec<O: VecN, R: VecN>: VecN { | |
fn map_with<F: Fn(Self::Item, O::Item) -> R::Item>(&self, o: O, f: F) -> R; | |
} | |
// BINARY TO SCALAR OPERATORS | |
trait BinToScal<O: VecN, R>: VecN { | |
} | |
// CONVERSION TRAITS | |
trait ConvFrom<T> { fn conv_from(a: T) -> Self; } | |
trait ConvTo<T> { fn to(self) -> T; } | |
impl<T, U> ConvTo<U> for T | |
where U: ConvFrom<T> | |
{ | |
fn to(self) -> U { | |
U::conv_from(self) | |
} | |
} | |
// Binary operations | |
impl<T: VecItem + Add<Output=T>> Add for Vec3<T> { | |
type Output = Vec3<T>; | |
fn add(self, o: Self) -> Self::Output { | |
self.map_with(o, |a, b| a + b) | |
} | |
} | |
// ITEM IMPLEMENTATIONS | |
impl VecItem for u8 {} | |
impl VecItem for u16 {} | |
impl VecItem for u32 {} | |
impl VecItem for u64 {} | |
impl VecItem for i8 {} | |
impl VecItem for i16 {} | |
impl VecItem for i32 {} | |
impl VecItem for i64 {} | |
impl VecItem for f32 {} | |
impl VecItem for f64 {} | |
impl VecItem for bool {} | |
impl VecItem for &'static str {} | |
macro_rules! impl_primitive_conv_from { | |
($from:ty, $to:ty) => { | |
impl ConvFrom<$from> for $to { | |
fn conv_from(a: $from) -> Self { a as Self } | |
} | |
} | |
} | |
impl_primitive_conv_from!(i8 , f32); | |
impl_primitive_conv_from!(i16, f32); | |
impl_primitive_conv_from!(i32, f32); | |
impl_primitive_conv_from!(i64, f32); | |
impl_primitive_conv_from!(f32, f32); | |
impl_primitive_conv_from!(f64, f32); | |
impl_primitive_conv_from!(i8 , f64); | |
impl_primitive_conv_from!(i16, f64); | |
impl_primitive_conv_from!(i32, f64); | |
impl_primitive_conv_from!(i64, f64); | |
impl_primitive_conv_from!(f32, f64); | |
impl_primitive_conv_from!(f64, f64); | |
impl_primitive_conv_from!(u8 , i64); | |
impl_primitive_conv_from!(u16, i64); | |
impl_primitive_conv_from!(u32, i64); | |
impl_primitive_conv_from!(i8 , i64); | |
impl_primitive_conv_from!(i16, i64); | |
impl_primitive_conv_from!(i32, i64); | |
impl_primitive_conv_from!(i64, i64); | |
impl_primitive_conv_from!(u8 , u64); | |
impl_primitive_conv_from!(u16, u64); | |
impl_primitive_conv_from!(u32, u64); | |
impl_primitive_conv_from!(u64, u64); | |
impl_primitive_conv_from!(u8 , i32); | |
impl_primitive_conv_from!(u16, i32); | |
impl_primitive_conv_from!(i8 , i32); | |
impl_primitive_conv_from!(i16, i32); | |
impl_primitive_conv_from!(i32, i32); | |
impl_primitive_conv_from!(u8 , u32); | |
impl_primitive_conv_from!(u16, u32); | |
impl_primitive_conv_from!(u32, u32); | |
impl_primitive_conv_from!(u8 , i16); | |
impl_primitive_conv_from!(i8 , i16); | |
impl_primitive_conv_from!(i16, i16); | |
impl_primitive_conv_from!(u8 , u16); | |
impl_primitive_conv_from!(u16, u16); | |
impl_primitive_conv_from!(i8 , i8); | |
impl_primitive_conv_from!(u8 , u8); | |
// VEC3 | |
#[derive(Copy, Clone)] | |
struct Vec3<T: VecItem> { | |
x: T, | |
y: T, | |
z: T, | |
} | |
impl<T: VecItem> Vec3<T> { | |
fn new(x: T, y: T, z: T) -> Vec3<T> { | |
Vec3 { x, y, z } | |
} | |
} | |
impl<T: VecItem, U: VecItem> ConvFrom<Vec3<U>> for Vec3<T> | |
where T: ConvFrom<U> | |
{ | |
fn conv_from(a: Vec3<U>) -> Self { | |
a.map(|e| T::conv_from(e)) | |
} | |
} | |
// Unary to vector | |
impl<T: VecItem, R: VecItem> UnToVec<Vec3<R>> for Vec3<T> { | |
fn map<F: Fn(Self::Item) -> R>(&self, f: F) -> Vec3<R> { | |
Vec3 { | |
x: f(self.x), | |
y: f(self.y), | |
z: f(self.z), | |
} | |
} | |
} | |
// Unary to scalar | |
impl<T: VecItem, R> UnToScal<R> for Vec3<T> { | |
fn fold<F: Fn(Self::Item, R) -> R>(&self, a: R, f: F) -> R { | |
let a = f(self.x, a); | |
let a = f(self.y, a); | |
f(self.z, a) | |
} | |
fn fold_back<F: Fn(Self::Item, R) -> R>(&self, a: R, f: F) -> R { | |
let a = f(self.z, a); | |
let a = f(self.y, a); | |
f(self.x, a) | |
} | |
fn apply_to<F: Fn(Self::Item, &mut R)>(&self, a: &mut R, f: F) { | |
f(self.x, a); | |
f(self.y, a); | |
f(self.z, a); | |
} | |
} | |
// Binary to vector | |
impl<T: VecItem, O: VecItem, R: VecItem> BinToVec<Vec3<O>, Vec3<R>> for Vec3<T> { | |
fn map_with<F: Fn(Self::Item, O) -> R>(&self, o: Vec3<O>, f: F) -> Vec3<R> { | |
Vec3 { | |
x: f(self.x, o.x), | |
y: f(self.y, o.y), | |
z: f(self.z, o.z), | |
} | |
} | |
} | |
// Binary to scalar | |
impl<T: VecItem, O: VecItem, R> BinToScal<Vec3<O>, R> for Vec3<T> { | |
} | |
// Debug | |
impl<T: VecItem + fmt::Debug> fmt::Debug for Vec3<T> { | |
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
write!(f, "(x: {:?}, y: {:?}, z: {:?})", self.x, self.y, self.z) | |
} | |
} | |
// Display | |
impl<T: VecItem + fmt::Display> fmt::Display for Vec3<T> { | |
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
write!(f, "({}, {}, {})", self.x, self.y, self.z) | |
} | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
#[test] | |
fn basic() { | |
let _v0 = Vec3::new(0, 0, 0); | |
let _v1: Vec3<f32> = _v0.to(); | |
let _v2 = _v1.map(|e| e * 2.0); | |
fn test_pass<V: ConvTo<Vec3<f32>>>(_v: V) { | |
// Nothing yet | |
} | |
test_pass(_v0); | |
test_pass(_v1); | |
let _v0 = Vec3::new("x", "y", "z"); | |
let _v0 = Vec3::new(true, false, false); | |
let _v1 = Vec3::new(3.0, 7.0, 3.0); | |
let _v2 = _v0.map_with(_v1, |a, b| if a { b > 5.0 } else { true }); | |
let _t = Vec3::new(5, 7, 12).fold(0, |e, a| a + e); | |
println!("{:?}", Vec3::new(1.5, 2.5, 3.5)); | |
println!("{}", Vec3::new(4.5, 5.5, 6.5)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment