Skip to content

Commit

Permalink
Convert points with components of one type to another
Browse files Browse the repository at this point in the history
  • Loading branch information
tuzz committed Feb 13, 2019
1 parent 3d9c56c commit c208aa5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/geometry/point/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,28 @@ use generic_array::{ArrayLength, GenericArray};
pub struct Point<T, N: ArrayLength<T>> {
pub components: GenericArray<T, N>,
}

impl<T, N: ArrayLength<T>, I, X> From<I> for Point<T, N>
where I: IntoIterator<Item=T, IntoIter=X>,
X: ExactSizeIterator<Item=T>,
{
fn from(iter: I) -> Self {
Self { components: GenericArray::from_exact_iter(iter).unwrap() }
}
}

// NotEq is a marker trait that's auto-implemented on all 2-tuples...
pub auto trait NotEq { }

// ...except those with two values of the same type...
impl<T> !NotEq for (T, T) { }

impl<T, U, N: ArrayLength<T> + ArrayLength<U>> From<Point<U, N>> for Point<T, N>
where (T, U): NotEq, // ...which lets us add a trait bound that avoids a conflict
T: From<U>, // with the auto-implemented From<T> trait.
U: Copy,
{
fn from(p: Point<U, N>) -> Self {
p.components.iter().map(|&a| a.into()).into()
}
}
8 changes: 8 additions & 0 deletions src/geometry/point2/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,12 @@ mod conversions {
assert_eq!(subject.x(), 1);
assert_eq!(subject.y(), 2);
}

#[test]
fn it_can_build_a_point2_from_a_point2_with_different_component_types() {
let subject: Point2f = Point2i::new(1, 2).into();

assert_eq!(subject.x(), 1.0);
assert_eq!(subject.y(), 2.0);
}
}
13 changes: 13 additions & 0 deletions src/geometry/point3/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,16 @@ mod default {
assert_eq!(subject.z(), 0);
}
}

mod conversions {
use super::*;

#[test]
fn it_can_build_a_point3_from_a_point3_with_different_component_types() {
let subject: Point3f = Point3i::new(1, 2, 3).into();

assert_eq!(subject.x(), 1.0);
assert_eq!(subject.y(), 2.0);
assert_eq!(subject.z(), 3.0);
}
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![feature(optin_builtin_traits)]

mod geometry;

fn main() {
Expand Down

0 comments on commit c208aa5

Please sign in to comment.