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
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::ops::{
    Add, Sub,
    Mul, Div
};

/// A definition of a `(x, y)` or `(col, row)` point in 2D space.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Position(pub u16, pub u16);

impl Position {
    pub fn x(&self) -> u16 {
        self.0
    }

    pub fn y(&self) -> u16 {
        self.1
    }
}

impl Default for Position {
    fn default() -> Self {
        Self(0, 0)
    }
}

impl Add for Position {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Self(self.0 + rhs.0, self.1 + rhs.1)
    }
}

impl Sub for Position {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Self(self.0 - rhs.0, self.1 - rhs.1)
    }
}

impl Mul for Position {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        Self(self.0 * rhs.0, self.1 * rhs.1)
    }
}

impl Div for Position {
    type Output = Self;

    fn div(self, mut rhs: Self) -> Self::Output {
        if rhs.0 == 0 {
            rhs.0 = 1;
        }

        if rhs.1 == 0 {
            rhs.1 = 1;
        }

        Self(self.0 / rhs.0, self.1 / rhs.1)
    }
}

/// A definition of some size `(width, height)`. It is relative strictly to itself, and has no
/// positional meaning on its own.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Size(pub u16, pub u16);

impl Size {
    /// Builds and returns an `Iterator` over possible arbitrary `Position`s inside this size constraint.
    pub fn iter(&self) -> impl Iterator<Item = Position> + '_ {
        (0..self.1).flat_map(move |row| {
            (0..self.0).map(move |col| Position(col, row))
        })
    }

    pub fn width(&self) -> u16 {
        self.0
    }

    pub fn height(&self) -> u16 {
        self.1
    }
}

impl Default for Size {
    fn default() -> Self {
        Self(1, 1)
    }
}

impl Add for Size {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Self(self.0 + rhs.0, self.1 + rhs.1)
    }
}

impl Sub for Size {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Self(self.0 - rhs.0, self.1 - rhs.1)
    }
}

impl Mul for Size {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        Self(self.0 * rhs.0, self.1 * rhs.1)
    }
}

impl Div for Size {
    type Output = Self;

    fn div(self, mut rhs: Self) -> Self::Output {
        if rhs.0 == 0 {
            rhs.0 = 1;
        }

        if rhs.1 == 0 {
            rhs.1 = 1;
        }

        Self(self.0 / rhs.0, self.1 / rhs.1)
    }
}