1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use super::Number;
use std::ops::{Add, Sub, AddAssign, SubAssign};

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Vector<N: Number = f32> {
    pub x: N,
    pub y: N,
}

pub type Position<N = f32> = Vector<N>;

impl<N: Number> Vector<N> {
    pub fn new(x: N, y: N) -> Self {
        Self { x, y }
    }

    pub fn zero() -> Self {
        Self::new(N::zero(), N::zero())
    }

    pub fn none() -> Option<Self> {
        None
    }
}

impl<N: Number> Add for Vector<N> {
    type Output = Self;

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

impl<N: Number> Sub for Vector<N> {
    type Output = Self;

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

impl<N: Number> AddAssign for Vector<N> {
    fn add_assign(&mut self, other: Self) {
        self.x += other.x;
        self.y += other.y;
    }
}

impl<N: Number> SubAssign for Vector<N> {
    fn sub_assign(&mut self, other: Self) {
        self.x -= other.x;
        self.y -= other.y;
    }
}

impl<N: Number> From<(N, N)> for Vector<N> {
    fn from((x, y): (N, N)) -> Self {
        Self::new(x, y)
    }
}

impl<N: Number> Into<(N, N)> for Vector<N> {
    fn into(self) -> (N, N) {
        (self.x, self.y)
    }
}

#[cfg(test)]
mod tests {
    use super::Vector;

    #[test]
    fn test_operator() {
        let mut vec = Vector::<f32>::new(100.0, 50.0);
        vec = vec + Vector::<f32>::new(40.0, 20.0);
        assert_eq!(vec, Vector::<f32>::new(140.0, 70.0));
        vec = vec - Vector::<f32>::new(40.0, 70.0);
        assert_eq!(vec, Vector::<f32>::new(100.0, 0.0));
        vec += Vector::<f32>::new(20.0, 50.0);
        assert_eq!(vec, Vector::new(120.0, 50.0));
        vec -= Vector::<f32>::new(80.0, 10.0);
        assert_eq!(vec, Vector::new(40.0, 40.0));
    }
}