geometry: cut down on <> noise with associated types
This commit is contained in:
@ -1,19 +1,26 @@
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Mul, Sub, Add};
|
||||
use num::{One, pow, integer::Roots};
|
||||
use std::cmp::{min, max};
|
||||
|
||||
pub trait CoordinateSpace {}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
|
||||
pub struct Coordinates<T: CoordLimits<Data = T>, S: CoordinateSpace> {
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
space: PhantomData<S>,
|
||||
pub trait CoordinateOp: PartialOrd + PartialEq + Sub + Clone + Mul + Copy + One + Add + Eq + Debug where
|
||||
Self: Sub<Output=Self> {
|
||||
const MIN: Self;
|
||||
const MAX: Self;
|
||||
fn distance(x1: Self, y1: Self, x2: Self, y2: Self) -> Self;
|
||||
}
|
||||
|
||||
impl<T: CoordLimits<Data = T> + Debug, S: CoordinateSpace> Debug for Coordinates<T, S> {
|
||||
pub trait CoordinateSpace {
|
||||
type Data: CoordinateOp;
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
|
||||
pub struct Coordinates<S: CoordinateSpace> {
|
||||
pub x: S::Data,
|
||||
pub y: S::Data,
|
||||
}
|
||||
|
||||
impl<S: CoordinateSpace> Debug for Coordinates<S> where S::Data: Debug {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("@")
|
||||
.field(&self.x)
|
||||
@ -22,16 +29,7 @@ impl<T: CoordLimits<Data = T> + Debug, S: CoordinateSpace> Debug for Coordinates
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CoordLimits: PartialOrd + PartialEq + Sub + Clone + Mul + Copy + One + Add {
|
||||
type Data: CoordLimits;
|
||||
const MIN: Self::Data;
|
||||
const MAX: Self::Data;
|
||||
|
||||
fn distance(x1: Self, y1: Self, x2: Self, y2: Self) -> Self;
|
||||
}
|
||||
|
||||
impl CoordLimits for u8 {
|
||||
type Data = u8;
|
||||
impl CoordinateOp for u8 {
|
||||
const MIN: u8 = 0;
|
||||
const MAX: u8 = 255;
|
||||
|
||||
@ -41,8 +39,7 @@ impl CoordLimits for u8 {
|
||||
}
|
||||
}
|
||||
|
||||
impl CoordLimits for u16 {
|
||||
type Data = u16;
|
||||
impl CoordinateOp for u16 {
|
||||
const MIN: u16 = u16::MIN;
|
||||
const MAX: u16 = u16::MAX;
|
||||
|
||||
@ -51,8 +48,7 @@ impl CoordLimits for u16 {
|
||||
}
|
||||
}
|
||||
|
||||
impl CoordLimits for usize {
|
||||
type Data = usize;
|
||||
impl CoordinateOp for usize {
|
||||
const MIN: usize = usize::MIN;
|
||||
const MAX: usize = usize::MAX;
|
||||
|
||||
@ -61,57 +57,51 @@ impl CoordLimits for usize {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: CoordLimits<Data = T>, S: CoordinateSpace> Coordinates<T, S> {
|
||||
pub const fn new(x: T, y: T) -> Self {
|
||||
impl<S: CoordinateSpace> Coordinates<S> {
|
||||
pub const fn new(x: S::Data, y: S::Data) -> Self {
|
||||
Self {
|
||||
x,
|
||||
y,
|
||||
space: PhantomData,
|
||||
y
|
||||
}
|
||||
}
|
||||
|
||||
fn top_left() -> Self {
|
||||
Self::new(T::MIN, T::MIN)
|
||||
Self::new(S::Data::MIN, S::Data::MIN)
|
||||
}
|
||||
|
||||
fn top_right() -> Self {
|
||||
Self::new(T::MAX, T::MIN)
|
||||
Self::new(S::Data::MAX, S::Data::MIN)
|
||||
}
|
||||
|
||||
fn bottom_left() -> Self {
|
||||
Self::new(T::MIN, T::MAX)
|
||||
Self::new(S::Data::MIN, S::Data::MAX)
|
||||
}
|
||||
|
||||
fn bottom_right() -> Self {
|
||||
Self::new(T::MAX, T::MAX)
|
||||
Self::new(S::Data::MAX, S::Data::MAX)
|
||||
}
|
||||
|
||||
pub fn distance_to(&self, other: &Self) -> T {
|
||||
T::distance(self.x, other.x, self.y, other.y)
|
||||
pub fn distance_to(&self, other: &Self) -> S::Data {
|
||||
S::Data::distance(self.x, other.x, self.y, other.y)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
pub struct Virtual {}
|
||||
impl CoordinateSpace for Virtual {}
|
||||
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
pub struct Coord8<S: CoordinateSpace> {
|
||||
x: u8,
|
||||
y: u8,
|
||||
space: PhantomData<S>
|
||||
impl CoordinateSpace for Virtual {
|
||||
type Data = u8;
|
||||
}
|
||||
|
||||
pub type VirtualCoordinates = Coordinates<u8, Virtual>;
|
||||
pub type VirtualCoordinates = Coordinates<Virtual>;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug, PartialOrd)]
|
||||
pub struct Rectangle<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> {
|
||||
pub top_left: Coordinates<CoordData, Space>,
|
||||
pub bottom_right: Coordinates<CoordData, Space>
|
||||
pub struct Rectangle<Space: CoordinateSpace> {
|
||||
pub top_left: Coordinates<Space>,
|
||||
pub bottom_right: Coordinates<Space>
|
||||
}
|
||||
|
||||
impl<CoordData: CoordLimits<Data = CoordData> + Sub<Output=CoordData>, Space: CoordinateSpace> Rectangle<CoordData, Space> {
|
||||
pub fn new(top_left: Coordinates<CoordData, Space>, bottom_right: Coordinates<CoordData, Space>) -> Self {
|
||||
impl<Space: CoordinateSpace> Rectangle<Space> {
|
||||
pub fn new(top_left: Coordinates<Space>, bottom_right: Coordinates<Space>) -> Self {
|
||||
debug_assert!(top_left.x <= bottom_right.x);
|
||||
debug_assert!(top_left.y <= bottom_right.y);
|
||||
Self {
|
||||
@ -122,32 +112,32 @@ impl<CoordData: CoordLimits<Data = CoordData> + Sub<Output=CoordData>, Space: Co
|
||||
|
||||
pub fn everything() -> Self {
|
||||
Self {
|
||||
top_left: Coordinates::<CoordData, Space>::top_left(),
|
||||
bottom_right: Coordinates::<CoordData, Space>::bottom_right()
|
||||
top_left: Coordinates::<Space>::top_left(),
|
||||
bottom_right: Coordinates::<Space>::bottom_right()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> CoordData {
|
||||
pub fn width(&self) -> Space::Data {
|
||||
self.bottom_right.x.clone() - self.top_left.x.clone()
|
||||
}
|
||||
|
||||
pub fn height(&self) -> CoordData {
|
||||
pub fn height(&self) -> Space::Data {
|
||||
self.bottom_right.y.clone() - self.top_left.y.clone()
|
||||
}
|
||||
|
||||
pub const fn left(&self) -> CoordData {
|
||||
pub const fn left(&self) -> Space::Data {
|
||||
self.top_left.x
|
||||
}
|
||||
|
||||
pub const fn top(&self) -> CoordData {
|
||||
pub const fn top(&self) -> Space::Data {
|
||||
self.top_left.y
|
||||
}
|
||||
|
||||
pub const fn right (&self) -> CoordData {
|
||||
pub const fn right (&self) -> Space::Data {
|
||||
self.bottom_right.x
|
||||
}
|
||||
|
||||
pub const fn bottom(&self) -> CoordData {
|
||||
pub const fn bottom(&self) -> Space::Data {
|
||||
self.bottom_right.y
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user